UNPKG

12.2 kBJavaScriptView Raw
1var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5 return c > 3 && r && Object.defineProperty(target, key, r), r;
6};
7var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11};
12var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
13 if (kind === "m") throw new TypeError("Private method is not writable");
14 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
15 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
16 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
17};
18var _DuoyunCascaderElement_instances, _DuoyunCascaderElement_value_get, _DuoyunCascaderElement_deep, _DuoyunCascaderElement_valueObj, _DuoyunCascaderElement_onChange, _DuoyunCascaderElement_onClick;
19var DuoyunCascaderElement_1;
20import { adoptedStyle, customElement, globalemitter, property, boolattribute, part, } from '@mantou/gem/lib/decorators';
21import { GemElement, html } from '@mantou/gem/lib/element';
22import { createCSSSheet, css, styleMap, classMap } from '@mantou/gem/lib/utils';
23import { icons } from '../lib/icons';
24import { structuredClone, getCascaderDeep, readProp } from '../lib/utils';
25import { theme } from '../lib/theme';
26import { isNotNullish } from '../lib/types';
27import './use';
28import './checkbox';
29const style = createCSSSheet(css `
30 :host(:where(:not([hidden]))) {
31 display: flex;
32 align-items: stretch;
33 }
34 .list {
35 box-sizing: border-box;
36 margin: 0;
37 padding: 0.2em 0;
38 width: 12em;
39 overflow: auto;
40 }
41 .list + .list {
42 border-inline-start: 1px solid ${theme.borderColor};
43 }
44 .item {
45 display: flex;
46 align-items: center;
47 gap: 0.5em;
48 line-height: 1.6;
49 padding: 0.3em 0.3em 0.3em 0.6em;
50 }
51 .item:hover,
52 .item.selected {
53 background-color: ${theme.lightBackgroundColor};
54 }
55 .checkbox {
56 margin-inline-start: 0.2em;
57 }
58 .label {
59 cursor: default;
60 flex-grow: 1;
61 overflow: hidden;
62 text-overflow: ellipsis;
63 white-space: nowrap;
64 }
65 .right {
66 width: 1.2em;
67 }
68`);
69const token = Symbol();
70/**
71 * @customElement dy-cascader
72 * @attr fit
73 * @attr multiple
74 */
75let DuoyunCascaderElement = DuoyunCascaderElement_1 = class DuoyunCascaderElement extends GemElement {
76 constructor() {
77 super(...arguments);
78 _DuoyunCascaderElement_instances.add(this);
79 this.state = {
80 selected: [],
81 };
82 _DuoyunCascaderElement_deep.set(this, 1);
83 _DuoyunCascaderElement_valueObj.set(this, {});
84 _DuoyunCascaderElement_onChange.set(this, (index, item, evt) => {
85 var _a;
86 evt.stopPropagation();
87 const valueClone = structuredClone(__classPrivateFieldGet(this, _DuoyunCascaderElement_valueObj, "f"));
88 let obj = valueClone;
89 // set new value(select part)
90 for (let i = 0; i < index; i++) {
91 const { value, label } = this.state.selected[i];
92 const k = value !== null && value !== void 0 ? value : label;
93 if (!obj[k])
94 obj[k] = {};
95 obj = obj[k];
96 }
97 // set new value(children part)
98 const generator = (item) => item.children
99 ? item.children.reduce((p, c) => {
100 var _a;
101 const v = generator(c);
102 const k = (_a = c.value) !== null && _a !== void 0 ? _a : c.label;
103 if (v === false) {
104 delete p[k];
105 }
106 else {
107 p[k] = generator(c);
108 }
109 return p;
110 }, {})
111 : evt.detail;
112 obj[(_a = item.value) !== null && _a !== void 0 ? _a : item.label] = generator(item);
113 // parse obj to array
114 const value = [];
115 const parse = (obj, init) => {
116 const keys = Object.keys(obj);
117 keys.forEach((key) => {
118 if (obj[key] === true) {
119 value.push([...init, key]);
120 }
121 parse(obj[key], [...init, key]);
122 });
123 };
124 parse(valueClone, []);
125 this.change(value);
126 });
127 _DuoyunCascaderElement_onClick.set(this, (index, item) => {
128 const { selected } = this.state;
129 const clickValue = selected.slice(0, index).concat(item);
130 if (selected[index] !== item) {
131 this.setState({ selected: clickValue });
132 }
133 if (!this.multiple && !item.children) {
134 this.change(clickValue.map((e) => { var _a; return (_a = e.value) !== null && _a !== void 0 ? _a : e.label; }));
135 }
136 });
137 this.willMount = () => {
138 this.memo(() => {
139 var _a, _b;
140 if (!this.options)
141 return;
142 __classPrivateFieldSet(this, _DuoyunCascaderElement_deep, getCascaderDeep(this.options, 'children'), "f");
143 // init state
144 if (!this.state.selected.length) {
145 const selected = [];
146 (_b = (_a = __classPrivateFieldGet(this, _DuoyunCascaderElement_instances, "a", _DuoyunCascaderElement_value_get)) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.forEach((val, index) => {
147 const item = (index ? selected[selected.length - 1].children : this.options).find((e) => { var _a; return val === ((_a = e.value) !== null && _a !== void 0 ? _a : e.label); });
148 selected.push(item);
149 });
150 this.setState({ selected });
151 }
152 }, () => [this.options]);
153 this.memo(() => {
154 var _a, _b;
155 // generator obj via value(array)
156 __classPrivateFieldSet(this, _DuoyunCascaderElement_valueObj, ((_a = __classPrivateFieldGet(this, _DuoyunCascaderElement_instances, "a", _DuoyunCascaderElement_value_get)) === null || _a === void 0 ? void 0 : _a.reduce((p, value) => {
157 value.reduce((pp, s, index, arr) => {
158 if (index === arr.length - 1) {
159 pp[s] = true;
160 return pp;
161 }
162 else {
163 return (pp[s] = pp[s] || {});
164 }
165 }, p);
166 return p;
167 }, {})) || {}, "f");
168 // append check status to obj via value(array)
169 const check = (path, item) => {
170 var _a, _b;
171 const key = String((_a = item.value) !== null && _a !== void 0 ? _a : item.label);
172 const sub = readProp(__classPrivateFieldGet(this, _DuoyunCascaderElement_valueObj, "f"), [...path, key]);
173 if (sub === true || !sub)
174 return;
175 const keys = Object.keys(sub);
176 if (!keys.length)
177 sub[token] = -1;
178 sub[token] = ((_b = item.children) === null || _b === void 0 ? void 0 : _b.every((e) => {
179 var _a;
180 const k = String((_a = e.value) !== null && _a !== void 0 ? _a : e.label);
181 if (sub[k] === true) {
182 return true;
183 }
184 else {
185 check([...path, key], e);
186 if (sub[k] && sub[k][token] === 1)
187 return true;
188 }
189 }))
190 ? 1
191 : 0;
192 };
193 (_b = this.options) === null || _b === void 0 ? void 0 : _b.forEach((e) => check([], e));
194 }, () => [this.value]);
195 };
196 this.render = () => {
197 if (!this.options)
198 return html ``;
199 const { selected } = this.state;
200 const listStyle = styleMap({ width: this.fit ? `${100 / __classPrivateFieldGet(this, _DuoyunCascaderElement_deep, "f")}%` : undefined });
201 return html `
202 ${[this.options, ...selected.map((e) => e.children).filter(isNotNullish)].map((list, index) => html `
203 <ul part=${DuoyunCascaderElement_1.column} class="list" style=${listStyle}>
204 ${list.map((item, _i, _arr, status = readProp(__classPrivateFieldGet(this, _DuoyunCascaderElement_valueObj, "f"), [...selected.slice(0, index), item].map((e) => { var _a; return String((_a = e.value) !== null && _a !== void 0 ? _a : e.label); }))) => {
205 var _a;
206 return html `
207 <li
208 class=${classMap({ item: true, selected: selected[index] === item })}
209 @click=${() => __classPrivateFieldGet(this, _DuoyunCascaderElement_onClick, "f").call(this, index, item)}
210 >
211 ${this.multiple
212 ? html `
213 <dy-checkbox
214 class="checkbox"
215 @change=${(evt) => __classPrivateFieldGet(this, _DuoyunCascaderElement_onChange, "f").call(this, index, item, evt)}
216 ?checked=${status === true || (status === null || status === void 0 ? void 0 : status[token]) === 1}
217 ?indeterminate=${status !== true && (status === null || status === void 0 ? void 0 : status[token]) === 0}
218 ></dy-checkbox>
219 `
220 : ''}
221 <span class="label">${(_a = item.value) !== null && _a !== void 0 ? _a : item.label}</span>
222 <dy-use class="right" .element=${item.children && icons.right}></dy-use>
223 </li>
224 `;
225 })}
226 </ul>
227 `)}
228 `;
229 };
230 }
231};
232_DuoyunCascaderElement_deep = new WeakMap(), _DuoyunCascaderElement_valueObj = new WeakMap(), _DuoyunCascaderElement_onChange = new WeakMap(), _DuoyunCascaderElement_onClick = new WeakMap(), _DuoyunCascaderElement_instances = new WeakSet(), _DuoyunCascaderElement_value_get = function _DuoyunCascaderElement_value_get() {
233 if (!this.value)
234 return;
235 return (this.multiple ? this.value : [this.value]);
236};
237__decorate([
238 property
239], DuoyunCascaderElement.prototype, "options", void 0);
240__decorate([
241 boolattribute
242], DuoyunCascaderElement.prototype, "fit", void 0);
243__decorate([
244 boolattribute
245], DuoyunCascaderElement.prototype, "multiple", void 0);
246__decorate([
247 globalemitter
248], DuoyunCascaderElement.prototype, "change", void 0);
249__decorate([
250 property
251], DuoyunCascaderElement.prototype, "value", void 0);
252__decorate([
253 part
254], DuoyunCascaderElement, "column", void 0);
255DuoyunCascaderElement = DuoyunCascaderElement_1 = __decorate([
256 customElement('dy-cascader'),
257 adoptedStyle(style)
258], DuoyunCascaderElement);
259export { DuoyunCascaderElement };
260//# sourceMappingURL=cascader.js.map
\No newline at end of file