fancy-ui-ts 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +9 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.js +101 -18
- package/package.json +15 -1
package/dist/index.css
CHANGED
|
@@ -129,6 +129,9 @@
|
|
|
129
129
|
--fc-error-fg: var(--fc-danger-300);
|
|
130
130
|
--fc-error-max-width: fit-content;
|
|
131
131
|
--fc-error-font-size: var(--fc-font-size-sm);
|
|
132
|
+
--fc-label-font-size: var(--fc-font-size-md);
|
|
133
|
+
--fc-label-font-weight: var(--fc-font-weight-bold);
|
|
134
|
+
--fc-label-fg: var(--fc-gray-900);
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
/* src/styles/themes/fc-theme-light.css */
|
|
@@ -180,6 +183,9 @@
|
|
|
180
183
|
--fc-input-radius: var(--fc-radius-md);
|
|
181
184
|
--fc-input-shadow: var(--fc-shadow-none);
|
|
182
185
|
--fc-error-fg: var(--fc-danger-300);
|
|
186
|
+
--fc-label-font-size: var(--fc-font-size-md);
|
|
187
|
+
--fc-label-font-weight: var(--fc-font-weight-bold);
|
|
188
|
+
--fc-label-fg: var(--fc-gray-900);
|
|
183
189
|
}
|
|
184
190
|
|
|
185
191
|
/* src/styles/themes/fc-theme-dark.css */
|
|
@@ -231,4 +237,7 @@
|
|
|
231
237
|
--fc-input-radius: var(--fc-radius-md);
|
|
232
238
|
--fc-input-shadow: var(--fc-shadow-none);
|
|
233
239
|
--fc-error-fg: var(--fc-danger-700);
|
|
240
|
+
--fc-label-font-size: var(--fc-font-size-md);
|
|
241
|
+
--fc-label-font-weight: var(--fc-font-weight-bold);
|
|
242
|
+
--fc-label-fg: var(--fc-gray-200);
|
|
234
243
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -168,6 +168,20 @@ declare class FcError extends HTMLElement {
|
|
|
168
168
|
|
|
169
169
|
declare const defineError: () => typeof FcError;
|
|
170
170
|
|
|
171
|
+
declare class FcLabel extends HTMLElement {
|
|
172
|
+
static get observedAttributes(): string[];
|
|
173
|
+
constructor();
|
|
174
|
+
connectedCallback(): void;
|
|
175
|
+
disconnectedCallback(): void;
|
|
176
|
+
attributeChangedCallback(name: string, _oldVal: string, newVal: string): void;
|
|
177
|
+
get htmlFor(): string;
|
|
178
|
+
set htmlFor(val: string);
|
|
179
|
+
private onClick;
|
|
180
|
+
setProps(props: Record<string, any>): void;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
declare const defineLabel: () => typeof FcLabel;
|
|
184
|
+
|
|
171
185
|
declare const defineAll: () => void;
|
|
172
186
|
|
|
173
|
-
export { FcCombobox, FcError, FcInput, FcOption, defineAll, defineCombobox, defineError, defineInput, defineOption };
|
|
187
|
+
export { FcCombobox, FcError, FcInput, FcLabel, FcOption, defineAll, defineCombobox, defineError, defineInput, defineLabel, defineOption };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
var styles = `\n\t:host {\n\t\tdisplay: block;\n\t\tposition: relative;\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n \tfont-family: var(--fc-font-family);\n\t\tmax-width: var(--fc-combobox-max-width);\n\t}\n\n\t/* only show invalid style if the user has touched the field (blurred). the :invalid pseudo-class comes from \n\tinternals.setValidity() logic. */\n\n\t:host([touched]:invalid) .fc-input {\n background-color: var(--fc-combobox-bg-error);\n border-color: var(--fc-combobox-border-error);\n }\n\n :host([touched]:invalid) .fc-input:focus {\n box-shadow: 0 0 0 2px var(--fc-combobox-focus-ring-error);\n }\n\n\t.fc-input {\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n\n\t\tpadding: var(--fc-combobox-padding);\n\t\tborder-radius: var(--fc-combobox-radius);\n\t\tbackground: var(--fc-combobox-bg);\n\t\tcolor: var(--fc-combobox-fg);\n\n\t\tborder: var(--fc-combobox-border-width) solid var(--fc-combobox-border);\n\t\tfont-size: var(--fc-font-size-md);\n\n\t\tbox-shadow: var(--fc-combobox-shadow);\n\t\ttransition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n\t}\n\n\t.fc-input::placeholder {\n\t\tcolor: var(--fc-combobox-placeholder);\n\t}\n\n\t.fc-input:hover {\n\t\tborder-color: var(--fc-combobox-border-hover);\n\t}\n\n\t.fc-input:focus {\n\t\tborder-color: var(--fc-combobox-border-focus);\n\t\toutline: none;\n\t\tbox-shadow: var(--fc-combobox-focus-ring);\n\t}\n\n\t.fc-options {\n\t\tposition: absolute;\n\t\ttop: calc(100% + 6px);\n\t\tleft: 0;\n\t\tright: 0;\n\t\tz-index: 1000;\n\t\tbackground: var(--fc-combobox-dropdown-bg, var(--fc-combobox-bg));\n\t\tborder: var(--fc-combobox-border-width) solid var(--fc-combobox-border);\n\t\tborder-radius: var(--fc-combobox-dropdown-radius, var(--fc-combobox-radius));\n\t\tpadding: var(--fc-combobox-dropdown-padding, calc(var(--fc-combobox-padding) - 5px));\n\t\tbox-shadow: var(--fc-combobox-dropdown-shadow);\n\t\tmax-height: var(--fc-combobox-dropdown-max-height, 240px);\n\t\toverflow-y: auto;\n\t\tbox-sizing: border-box;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tgap: 4px;\n\t}\n\t\n\t.fc-options[hidden] {\n display: none !important;\n }\n\n\t:host([disabled]) {\n cursor: not-allowed;\n }\n\n\t.fc-input:disabled {\n\t\tbackground: var(--fc-combobox-bg-disabled);\n cursor: not-allowed;\n\t\tbox-shadow: none;\n }\n\n\t.fc-input:disabled::placeholder {\n\t\tcolor: var(--fc-combobox-placeholder-disabled);\n }\n\n\t.fc-input:disabled:hover {\n\t\tborder-color: var(--fc-combobox-border);\n\t}\n\n\t.fc-input:disabled:focus {\n\t\tborder-color: var(--fc-combobox-border);\n\t}\n`;
|
|
1
|
+
var styles = `\n\t:host {\n\t\tdisplay: block;\n\t\tposition: relative;\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n \tfont-family: var(--fc-font-family);\n\t\tmax-width: var(--fc-combobox-max-width);\n\t}\n\n\t/* only show invalid style if the user has touched the field (blurred). the :invalid pseudo-class comes from \n\tinternals.setValidity() logic. */\n\n\t:host([touched]:invalid) .fc-input {\n background-color: var(--fc-combobox-bg-error);\n border-color: var(--fc-combobox-border-error);\n }\n\n :host([touched]:invalid) .fc-input:focus {\n box-shadow: 0 0 0 2px var(--fc-combobox-focus-ring-error);\n }\n\n\t.fc-input {\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n\n\t\tpadding: var(--fc-combobox-padding);\n\t\tborder-radius: var(--fc-combobox-radius);\n\t\tbackground: var(--fc-combobox-bg);\n\t\tcolor: var(--fc-combobox-fg);\n\n\t\tborder: var(--fc-combobox-border-width) solid var(--fc-combobox-border);\n\t\tfont-size: var(--fc-font-size-md);\n\n\t\tbox-shadow: var(--fc-combobox-shadow);\n\t\ttransition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n\t}\n\n\t.fc-input::placeholder {\n\t\tcolor: var(--fc-combobox-placeholder);\n\t}\n\n\t.fc-input:hover {\n\t\tborder-color: var(--fc-combobox-border-hover);\n\t}\n\n\t.fc-input:focus {\n\t\tborder-color: var(--fc-combobox-border-focus);\n\t\toutline: none;\n\t\tbox-shadow: var(--fc-combobox-focus-ring);\n\t}\n\n\t.fc-options {\n\t\tposition: absolute;\n\t\ttop: calc(100% + 6px);\n\t\tleft: 0;\n\t\tright: 0;\n\t\tz-index: 1000;\n\t\tbackground: var(--fc-combobox-dropdown-bg, var(--fc-combobox-bg));\n\t\tborder: var(--fc-combobox-border-width) solid var(--fc-combobox-border);\n\t\tborder-radius: var(--fc-combobox-dropdown-radius, var(--fc-combobox-radius));\n\t\tpadding: var(--fc-combobox-dropdown-padding, calc(var(--fc-combobox-padding) - 5px));\n\t\tbox-shadow: var(--fc-combobox-dropdown-shadow);\n\t\tmax-height: var(--fc-combobox-dropdown-max-height, 240px);\n\t\toverflow-y: auto;\n\t\tbox-sizing: border-box;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tgap: 4px;\n\t}\n\n\t.fc-options.opens-up {\n top: auto;\n bottom: calc(100% + 6px);\n }\n\t\n\t.fc-options[hidden] {\n display: none !important;\n }\n\n\t:host([disabled]) {\n cursor: not-allowed;\n }\n\n\t.fc-input:disabled {\n\t\tbackground: var(--fc-combobox-bg-disabled);\n cursor: not-allowed;\n\t\tbox-shadow: none;\n }\n\n\t.fc-input:disabled::placeholder {\n\t\tcolor: var(--fc-combobox-placeholder-disabled);\n }\n\n\t.fc-input:disabled:hover {\n\t\tborder-color: var(--fc-combobox-border);\n\t}\n\n\t.fc-input:disabled:focus {\n\t\tborder-color: var(--fc-combobox-border);\n\t}\n`;
|
|
2
2
|
|
|
3
3
|
var template = document.createElement("template");
|
|
4
4
|
|
|
5
5
|
template.innerHTML = `\n\t<style>${styles}</style>\n\n\t<input \n\t\tclass="fc-input"\n\t\ttype="text" \n\t\trole="combobox"\n\t\taria-autocomplete="list"\n\t\taria-expanded="false"\n\t\taria-haspopup="listbox"\n\t\taria-controls="fc-options"\n\t\tpart="input"\n\t\tautocomplete="off"\n\t/>\n\n\t<div \n\t\tpart="options" \n\t\tclass="fc-options" \n\t\trole="listbox"\n\t\thidden\n\t>\n\t\t<slot></slot>\n\t</div>\n\t\n`;
|
|
6
6
|
|
|
7
|
+
var calculateBottomAvaliableSpace = element => {
|
|
8
|
+
const rect = element.getBoundingClientRect();
|
|
9
|
+
const viewportHeight = window.innerHeight;
|
|
10
|
+
return viewportHeight - rect.bottom;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
var calculateTopAvaliableSpace = element => {
|
|
14
|
+
const rect = element.getBoundingClientRect();
|
|
15
|
+
return rect.top;
|
|
16
|
+
};
|
|
17
|
+
|
|
7
18
|
var FcCombobox = class extends HTMLElement {
|
|
8
19
|
constructor() {
|
|
9
20
|
super();
|
|
@@ -89,19 +100,6 @@ var FcCombobox = class extends HTMLElement {
|
|
|
89
100
|
if (!this.inputEl) {
|
|
90
101
|
return;
|
|
91
102
|
}
|
|
92
|
-
const options = this.querySelectorAll("fc-option");
|
|
93
|
-
options.forEach(option => {
|
|
94
|
-
const selected = option.value === newValue;
|
|
95
|
-
option.selected = selected;
|
|
96
|
-
option.hidden = !selected;
|
|
97
|
-
option.active = false;
|
|
98
|
-
if (selected) {
|
|
99
|
-
this.inputEl.value = option.label;
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
if (this.inputEl.value === "") {
|
|
103
|
-
this.inputEl.value = newValue;
|
|
104
|
-
}
|
|
105
103
|
this.syncValidity();
|
|
106
104
|
}
|
|
107
105
|
get label() {
|
|
@@ -256,12 +254,23 @@ var FcCombobox = class extends HTMLElement {
|
|
|
256
254
|
this._value = restoredValue;
|
|
257
255
|
this.internals.setFormValue(restoredValue);
|
|
258
256
|
const options = this.querySelectorAll("fc-option");
|
|
257
|
+
let foundMatch = false;
|
|
259
258
|
options.forEach(option => {
|
|
260
|
-
|
|
259
|
+
const selected = option.value === this._value;
|
|
260
|
+
option.selected = selected;
|
|
261
|
+
option.hidden = !selected;
|
|
262
|
+
if (selected) {
|
|
261
263
|
this.inputEl.value = option.label;
|
|
262
|
-
|
|
264
|
+
foundMatch = true;
|
|
263
265
|
}
|
|
264
266
|
});
|
|
267
|
+
if (!foundMatch && this.inputEl.value === "") {
|
|
268
|
+
this.inputEl.value = this._value;
|
|
269
|
+
options.forEach(option => {
|
|
270
|
+
const match = option.label.includes(this._value);
|
|
271
|
+
option.hidden = !match;
|
|
272
|
+
});
|
|
273
|
+
}
|
|
265
274
|
this.syncValidity();
|
|
266
275
|
}
|
|
267
276
|
}
|
|
@@ -393,7 +402,6 @@ var FcCombobox = class extends HTMLElement {
|
|
|
393
402
|
const selected = option.value === this._value;
|
|
394
403
|
option.selected = selected;
|
|
395
404
|
option.hidden = !selected;
|
|
396
|
-
option.active = false;
|
|
397
405
|
if (selected) {
|
|
398
406
|
this.inputEl.value = option.label;
|
|
399
407
|
foundMatch = true;
|
|
@@ -401,6 +409,11 @@ var FcCombobox = class extends HTMLElement {
|
|
|
401
409
|
});
|
|
402
410
|
if (!foundMatch && this.inputEl.value === "") {
|
|
403
411
|
this.inputEl.value = this._value;
|
|
412
|
+
options.forEach(option => {
|
|
413
|
+
console.log(option.value);
|
|
414
|
+
const match = option.label.toLowerCase().includes(this._value.toLowerCase());
|
|
415
|
+
option.hidden = !match;
|
|
416
|
+
});
|
|
404
417
|
}
|
|
405
418
|
this.syncValidity();
|
|
406
419
|
}
|
|
@@ -492,9 +505,13 @@ var FcCombobox = class extends HTMLElement {
|
|
|
492
505
|
}
|
|
493
506
|
const dropdown = this.dropdownEl;
|
|
494
507
|
if (show) {
|
|
508
|
+
const spaceBelow = calculateBottomAvaliableSpace(this.inputEl);
|
|
509
|
+
const spaceAbove = calculateTopAvaliableSpace(this.inputEl);
|
|
495
510
|
dropdown.hidden = false;
|
|
496
511
|
this.setAttribute("open", "true");
|
|
497
512
|
this.inputEl.setAttribute("aria-expanded", "true");
|
|
513
|
+
const shouldOpenUp = spaceBelow < dropdown.clientHeight && spaceAbove > spaceBelow;
|
|
514
|
+
dropdown.classList.toggle("opens-up", shouldOpenUp);
|
|
498
515
|
return;
|
|
499
516
|
}
|
|
500
517
|
this.dropdownEl.hidden = true;
|
|
@@ -1236,11 +1253,77 @@ var defineError = () => {
|
|
|
1236
1253
|
return FcError;
|
|
1237
1254
|
};
|
|
1238
1255
|
|
|
1256
|
+
var styles5 = `\n :host {\n display: block;\n width: 100%;\n box-sizing: border-box;\n font-family: var(--fc-font-family, inherit);\n font-size: var(--fc-label-font-size);\n font-weight: var(--fc-label-font-weight);\n color: var(--fc-label-fg);\n cursor: pointer;\n line-height: 1.5;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .fc-label-text {\n display: flex;\n align-items: center;\n }\n`;
|
|
1257
|
+
|
|
1258
|
+
var template5 = document.createElement("template");
|
|
1259
|
+
|
|
1260
|
+
template5.innerHTML = `\n <style>${styles5}</style>\n <div class="fc-label-text" part="text">\n <slot></slot>\n </div>\n`;
|
|
1261
|
+
|
|
1262
|
+
var FcLabel = class extends HTMLElement {
|
|
1263
|
+
static get observedAttributes() {
|
|
1264
|
+
return [ "for" ];
|
|
1265
|
+
}
|
|
1266
|
+
constructor() {
|
|
1267
|
+
super();
|
|
1268
|
+
const shadow = this.attachShadow({
|
|
1269
|
+
mode: "open"
|
|
1270
|
+
});
|
|
1271
|
+
shadow.appendChild(template5.content.cloneNode(true));
|
|
1272
|
+
this.onClick = this.onClick.bind(this);
|
|
1273
|
+
}
|
|
1274
|
+
connectedCallback() {
|
|
1275
|
+
this.addEventListener("click", this.onClick);
|
|
1276
|
+
}
|
|
1277
|
+
disconnectedCallback() {
|
|
1278
|
+
this.removeEventListener("click", this.onClick);
|
|
1279
|
+
}
|
|
1280
|
+
attributeChangedCallback(name, _oldVal, newVal) {}
|
|
1281
|
+
get htmlFor() {
|
|
1282
|
+
var _a;
|
|
1283
|
+
return (_a = this.getAttribute("for")) != null ? _a : "";
|
|
1284
|
+
}
|
|
1285
|
+
set htmlFor(val) {
|
|
1286
|
+
this.setAttribute("for", val);
|
|
1287
|
+
}
|
|
1288
|
+
onClick(e) {
|
|
1289
|
+
e.preventDefault();
|
|
1290
|
+
const targetId = this.getAttribute("for");
|
|
1291
|
+
if (!targetId) {
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
const targetEl = document.getElementById(targetId);
|
|
1295
|
+
if (targetEl) {
|
|
1296
|
+
targetEl.focus();
|
|
1297
|
+
targetEl.click();
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
setProps(props) {
|
|
1301
|
+
for (const property in props) {
|
|
1302
|
+
const value = props[property];
|
|
1303
|
+
if (property in this) {
|
|
1304
|
+
this[property] = value;
|
|
1305
|
+
continue;
|
|
1306
|
+
}
|
|
1307
|
+
if ([ "string", "number", "boolean" ].includes(typeof value)) {
|
|
1308
|
+
this.setAttribute(property, String(value));
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
};
|
|
1313
|
+
|
|
1314
|
+
var defineLabel = () => {
|
|
1315
|
+
if (!customElements.get("fc-label")) {
|
|
1316
|
+
customElements.define("fc-label", FcLabel);
|
|
1317
|
+
}
|
|
1318
|
+
return FcLabel;
|
|
1319
|
+
};
|
|
1320
|
+
|
|
1239
1321
|
var defineAll = () => {
|
|
1240
1322
|
defineCombobox();
|
|
1241
1323
|
defineOption();
|
|
1242
1324
|
defineInput();
|
|
1243
1325
|
defineError();
|
|
1326
|
+
defineLabel();
|
|
1244
1327
|
};
|
|
1245
1328
|
|
|
1246
|
-
export { FcCombobox, FcError, FcInput, FcOption, defineAll, defineCombobox, defineError, defineInput, defineOption };
|
|
1329
|
+
export { FcCombobox, FcError, FcInput, FcLabel, FcOption, defineAll, defineCombobox, defineError, defineInput, defineLabel, defineOption };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fancy-ui-ts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A library to easily create cool and customizable webcomponents.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,6 +26,20 @@
|
|
|
26
26
|
"build": "tsup",
|
|
27
27
|
"build:watch": "tsup --watch"
|
|
28
28
|
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"web-components",
|
|
31
|
+
"components",
|
|
32
|
+
"custom-elements",
|
|
33
|
+
"typescript",
|
|
34
|
+
"ui-library",
|
|
35
|
+
"design-system",
|
|
36
|
+
"combobox",
|
|
37
|
+
"input",
|
|
38
|
+
"label",
|
|
39
|
+
"html",
|
|
40
|
+
"react",
|
|
41
|
+
"vue"
|
|
42
|
+
],
|
|
29
43
|
"author": "Luan Peixoto",
|
|
30
44
|
"license": "MIT",
|
|
31
45
|
"devDependencies": {
|