coles-solid-library 0.3.7 → 0.3.9
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.
|
@@ -14,6 +14,11 @@ export declare class FormGroup<T extends object> {
|
|
|
14
14
|
private meta;
|
|
15
15
|
private keys;
|
|
16
16
|
constructor(data: FormGroupData<T>);
|
|
17
|
+
/**
|
|
18
|
+
* INTERNAL: returns the reactive internal store reference (DO NOT MUTATE outside FormGroup).
|
|
19
|
+
* Used for bridging into FormContext without triggering cloning loops.
|
|
20
|
+
*/
|
|
21
|
+
_unsafeRaw(): T;
|
|
17
22
|
/**
|
|
18
23
|
* Gets the current form data or the value of a specific control.
|
|
19
24
|
*
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Accessor, Component, JSX, Setter } from "solid-js";
|
|
2
2
|
interface Props extends JSX.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/** Optional external accessor (legacy). If omitted and inside a FormField+Form, form data is used. */
|
|
4
|
+
text?: Accessor<string>;
|
|
5
|
+
/** Optional external setter (legacy). */
|
|
6
|
+
setText?: Setter<string>;
|
|
5
7
|
class?: string;
|
|
6
8
|
tooltip?: string;
|
|
7
9
|
transparent?: boolean;
|
package/dist/index.esm.js
CHANGED
|
@@ -1441,6 +1441,17 @@ const FormInner = props => {
|
|
|
1441
1441
|
const Provider = props => {
|
|
1442
1442
|
const defaultData = props.value ?? {};
|
|
1443
1443
|
const [data, setData] = createStore(defaultData);
|
|
1444
|
+
// Bridge: keep FormContext store in sync with underlying FormGroup reactive store
|
|
1445
|
+
// This allows programmatic calls to formGroup.set(...) to propagate into bound fields.
|
|
1446
|
+
createEffect(() => {
|
|
1447
|
+
const raw = props.formGroup._unsafeRaw(); // reactive read of underlying store
|
|
1448
|
+
for (const k in raw) {
|
|
1449
|
+
const nextVal = raw[k];
|
|
1450
|
+
if (data[k] !== nextVal) {
|
|
1451
|
+
setData(k, nextVal);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
});
|
|
1444
1455
|
return createComponent(FormContext.Provider, {
|
|
1445
1456
|
get value() {
|
|
1446
1457
|
return {
|
|
@@ -1588,40 +1599,62 @@ styleInject(css_248z$d);
|
|
|
1588
1599
|
var _tmpl$$h = /*#__PURE__*/template(`<label><input type=checkbox><span>`),
|
|
1589
1600
|
_tmpl$2$9 = /*#__PURE__*/template(`<span>`);
|
|
1590
1601
|
function Checkbox(props) {
|
|
1591
|
-
|
|
1602
|
+
const field = useFormProvider();
|
|
1603
|
+
const formCtx = useFormContext();
|
|
1604
|
+
const formName = field?.formName;
|
|
1605
|
+
// Internal state for uncontrolled usage outside form context
|
|
1592
1606
|
const [internalChecked, setInternalChecked] = createSignal(props.defaultChecked ?? false);
|
|
1593
|
-
|
|
1594
|
-
const
|
|
1595
|
-
|
|
1596
|
-
|
|
1607
|
+
// Derive current checked state with priority: controlled prop -> form context -> field local value -> internal state
|
|
1608
|
+
const checkedState = createMemo(() => {
|
|
1609
|
+
if (props.checked !== undefined) return !!props.checked;
|
|
1610
|
+
if (formName && formCtx?.data) return !!formCtx.data[formName];
|
|
1611
|
+
if (field?.getValue) return !!field.getValue();
|
|
1612
|
+
return internalChecked();
|
|
1613
|
+
});
|
|
1614
|
+
// Keep field/form floating states in sync if programmatic changes occur
|
|
1615
|
+
createEffect(() => {
|
|
1616
|
+
const c = checkedState();
|
|
1617
|
+
if (formName && formCtx?.data) {
|
|
1618
|
+
field?.setTextInside?.(c);
|
|
1619
|
+
field?.setValue?.(c);
|
|
1620
|
+
}
|
|
1621
|
+
});
|
|
1622
|
+
const commitValue = next => {
|
|
1597
1623
|
if (props.checked === undefined) {
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
});
|
|
1607
|
-
props.onChange?.(newChecked);
|
|
1624
|
+
if (formName && formCtx?.formGroup) {
|
|
1625
|
+
formCtx.formGroup.set(formName, next);
|
|
1626
|
+
formCtx.setData?.(formName, next);
|
|
1627
|
+
} else if (field?.setValue) {
|
|
1628
|
+
field.setValue(next);
|
|
1629
|
+
} else {
|
|
1630
|
+
setInternalChecked(next);
|
|
1631
|
+
}
|
|
1608
1632
|
}
|
|
1633
|
+
field?.setTextInside?.(next);
|
|
1634
|
+
props.onChange?.(next);
|
|
1609
1635
|
};
|
|
1610
|
-
const
|
|
1636
|
+
const handleChange = e => {
|
|
1637
|
+
const target = e.currentTarget;
|
|
1638
|
+
const newChecked = target.checked;
|
|
1611
1639
|
if (props.checked !== undefined) {
|
|
1612
|
-
|
|
1613
|
-
|
|
1640
|
+
// controlled: emit change; parent should update props.checked.
|
|
1641
|
+
// After microtask (allow parent reactive update) sync DOM to current checkedState
|
|
1642
|
+
props.onChange?.(newChecked);
|
|
1614
1643
|
queueMicrotask(() => {
|
|
1615
|
-
|
|
1644
|
+
// checkedState() reflects latest props / form context
|
|
1645
|
+
const desired = checkedState();
|
|
1646
|
+
if (target.checked !== desired) target.checked = desired;
|
|
1616
1647
|
});
|
|
1648
|
+
return;
|
|
1617
1649
|
}
|
|
1650
|
+
// uncontrolled / form-managed
|
|
1651
|
+
commitValue(newChecked);
|
|
1618
1652
|
};
|
|
1619
1653
|
return (() => {
|
|
1620
1654
|
var _el$ = _tmpl$$h(),
|
|
1621
1655
|
_el$2 = _el$.firstChild,
|
|
1622
1656
|
_el$3 = _el$2.nextSibling;
|
|
1623
1657
|
_el$2.addEventListener("change", handleChange);
|
|
1624
|
-
_el$2.$$click = handleClick;
|
|
1625
1658
|
insert(_el$, (() => {
|
|
1626
1659
|
var _c$ = createMemo(() => !!props.label);
|
|
1627
1660
|
return () => _c$() && (() => {
|
|
@@ -1660,7 +1693,6 @@ function Checkbox(props) {
|
|
|
1660
1693
|
return _el$;
|
|
1661
1694
|
})();
|
|
1662
1695
|
}
|
|
1663
|
-
delegateEvents(["click"]);
|
|
1664
1696
|
|
|
1665
1697
|
var css_248z$c = ".selectStyles-module_solid_select__placeholder__VO5-- {\n opacity: var(--text-emphasis-medium, 87%);\n transition: all 0.7s ease;\n}\n\n.selectStyles-module_solid_select__transparent__nOpvm {\n background-color: transparent;\n}\n\n.selectStyles-module_solid_select__3plh1 {\n display: inline-block;\n position: relative;\n background-color: var(--container-color, #ffffff);\n color: var(--on-container-color, #000);\n text-align: left;\n border-radius: 8px;\n width: 100%;\n margin: 0px 6px;\n}\n\n.selectStyles-module_solid_select__control__Wmmpg {\n display: flex;\n align-items: center;\n width: 100%;\n max-height: 48px;\n border-radius: 8px;\n background-color: var(--container-color, #ffffff);\n color: var(--on-container-color, #000);\n cursor: pointer;\n transition: border 0.7s ease, padding 0.7s ease;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.selectStyles-module_solid_select__control__Wmmpg:first-child {\n flex-grow: 1;\n}\n.selectStyles-module_solid_select__control__Wmmpg:last-child {\n padding: 0px 6px;\n margin: 0px;\n}\n\n.selectStyles-module_solid_select__control_no_form__Cq9Sc {\n display: flex;\n align-items: center;\n width: 100%;\n height: 48px;\n border-radius: 8px;\n width: 200px;\n margin-top: 2px;\n cursor: pointer;\n}\n.selectStyles-module_solid_select__control_no_form__Cq9Sc:first-child {\n flex-grow: 1;\n}\n.selectStyles-module_solid_select__control_no_form__Cq9Sc:last-child {\n padding: 0px 6px;\n margin: 0px;\n}\n\n.selectStyles-module_solid_select__arrow__OPCZo {\n font-size: 0.7em;\n}\n\n.selectStyles-module_solid_select__value__rNtqF {\n flex-grow: 1;\n transition: all 0.3s ease;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: block;\n}\n\n.selectStyles-module_multiselect-value__UUhhP {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 100%;\n}\n\n.selectStyles-module_solid_select__dropdown__UCt-N {\n position: absolute;\n background-color: var(--surface-color, #EEEEEE);\n top: 100%;\n left: 0;\n z-index: 999999999999999;\n max-height: 200px;\n border-radius: 8px;\n overflow-x: hidden;\n overflow-y: auto;\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\n transform-origin: top;\n transform: scaleY(0);\n transition: transform 0.3s ease-out, opacity 0.3s ease-out;\n opacity: 0;\n}\n\n.selectStyles-module_dropTop__IVz9p {\n transform-origin: bottom;\n}\n\n.selectStyles-module_dropBottom__cYJF0 {\n transform-origin: top;\n}\n\n.selectStyles-module_open__f8zLA {\n transform: scaleY(1);\n opacity: 1;\n}\n\n.selectStyles-module_solid_select__option__47WMY {\n padding: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n min-height: 32px;\n background-color: var(--container-color, #ffffff);\n color: var(--on-container-color, #000);\n border-radius: 8px;\n}\n.selectStyles-module_solid_select__option__47WMY:hover {\n border: 2px inset var(--primary-color-varient, #43A047);\n}\n.selectStyles-module_solid_select__option__47WMY:has(.selectStyles-module_selected__1-CKm) {\n font-weight: bold;\n}\n\n.selectStyles-module_checkmark__UWcbd {\n display: inline-block;\n width: 1.2em;\n margin-right: 4px;\n text-align: center;\n}\n\n.selectStyles-module_option-label__bBFSW {\n width: -moz-max-content;\n width: max-content;\n height: -moz-max-content;\n height: max-content;\n}";
|
|
1666
1698
|
var styles$7 = {"solid_select__placeholder":"selectStyles-module_solid_select__placeholder__VO5--","solid_select__transparent":"selectStyles-module_solid_select__transparent__nOpvm","solid_select":"selectStyles-module_solid_select__3plh1","solid_select__control":"selectStyles-module_solid_select__control__Wmmpg","solid_select__control_no_form":"selectStyles-module_solid_select__control_no_form__Cq9Sc","solid_select__arrow":"selectStyles-module_solid_select__arrow__OPCZo","solid_select__value":"selectStyles-module_solid_select__value__rNtqF","multiselect-value":"selectStyles-module_multiselect-value__UUhhP","solid_select__dropdown":"selectStyles-module_solid_select__dropdown__UCt-N","dropTop":"selectStyles-module_dropTop__IVz9p","dropBottom":"selectStyles-module_dropBottom__cYJF0","open":"selectStyles-module_open__f8zLA","solid_select__option":"selectStyles-module_solid_select__option__47WMY","selected":"selectStyles-module_selected__1-CKm","checkmark":"selectStyles-module_checkmark__UWcbd","option-label":"selectStyles-module_option-label__bBFSW"};
|
|
@@ -2006,6 +2038,9 @@ function Select(props) {
|
|
|
2006
2038
|
}
|
|
2007
2039
|
// store orientation for class assignment
|
|
2008
2040
|
setDropTop(placeAbove);
|
|
2041
|
+
// Compute available vertical space for dropdown and clamp to a sensible minimum
|
|
2042
|
+
const availableSpace = (placeAbove ? spaceAbove : spaceBelow) - VIEWPORT_MARGIN;
|
|
2043
|
+
const maxHeight = Math.max(160, availableSpace); // ensure at least 160px so a few options are visible
|
|
2009
2044
|
let newY;
|
|
2010
2045
|
if (!placeAbove) {
|
|
2011
2046
|
newY = baseRect.bottom + window.scrollY; // default below
|
|
@@ -2027,6 +2062,7 @@ function Select(props) {
|
|
|
2027
2062
|
dropdown.style.left = `${newX}px`;
|
|
2028
2063
|
dropdown.style.top = `${newY}px`;
|
|
2029
2064
|
dropdown.style.width = `${baseRect.width}px`;
|
|
2065
|
+
dropdown.style.maxHeight = `${maxHeight}px`;
|
|
2030
2066
|
};
|
|
2031
2067
|
// Update width of select to match option text width
|
|
2032
2068
|
createEffect(() => {
|
|
@@ -2178,7 +2214,6 @@ function Select(props) {
|
|
|
2178
2214
|
get children() {
|
|
2179
2215
|
var _el$12 = _tmpl$4$1();
|
|
2180
2216
|
use(setDropdownRef, _el$12);
|
|
2181
|
-
_el$12.style.setProperty("max-height", "calc(100vh - 8px)");
|
|
2182
2217
|
insert(_el$12, () => props.children);
|
|
2183
2218
|
createRenderEffect(_p$ => {
|
|
2184
2219
|
var _v$ = `${styles$7['solid_select__dropdown']} ${dropTop() ? styles$7.dropTop : styles$7.dropBottom} ${open() ? styles$7.open : ''} ${props.dropdownClass || ""}`,
|
|
@@ -2345,76 +2380,101 @@ var _tmpl$$e = /*#__PURE__*/template(`<textarea>`);
|
|
|
2345
2380
|
const TextArea = props => {
|
|
2346
2381
|
let myElement;
|
|
2347
2382
|
const [customProps, normalProps] = splitProps(props, ["minSize", "text", "setText", "class", "tooltip", "transparent"]);
|
|
2348
|
-
const
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2383
|
+
const fieldCtx = useFormProvider();
|
|
2384
|
+
const formCtx = useFormContext();
|
|
2385
|
+
const formName = fieldCtx?.formName;
|
|
2386
|
+
// Internal state only used when not provided externally and not in form context.
|
|
2387
|
+
const [internal, setInternal] = createSignal(customProps.text ? customProps.text() : "");
|
|
2388
|
+
// Determine current value priority: FormGroup -> external accessor -> internal state
|
|
2389
|
+
const areaValue = createMemo(() => {
|
|
2390
|
+
if (formName && formCtx?.data && !isNullish(formCtx.data[formName])) {
|
|
2391
|
+
return formCtx.data[formName];
|
|
2392
|
+
}
|
|
2393
|
+
if (customProps.text) return customProps.text();
|
|
2394
|
+
return internal();
|
|
2395
|
+
});
|
|
2396
|
+
function resizeToContent() {
|
|
2397
|
+
if (!myElement) return;
|
|
2398
|
+
myElement.style.height = 'auto';
|
|
2399
|
+
const minHeight = customProps.minSize?.height ?? 100;
|
|
2400
|
+
const currentHeight = Math.max(minHeight, myElement.scrollHeight);
|
|
2401
|
+
myElement.style.height = `${currentHeight}px`;
|
|
2402
|
+
myElement.style.overflowY = 'hidden';
|
|
2360
2403
|
}
|
|
2361
|
-
//
|
|
2404
|
+
// Set field type & initial floating state
|
|
2362
2405
|
onMount(() => {
|
|
2363
|
-
|
|
2364
|
-
|
|
2406
|
+
resizeToContent();
|
|
2407
|
+
fieldCtx?.setFieldType?.('textarea');
|
|
2408
|
+
if (formName && formCtx?.data) {
|
|
2409
|
+
const v = formCtx.data[formName];
|
|
2410
|
+
if (!isNullish(v) && String(v).trim() !== '') {
|
|
2411
|
+
fieldCtx?.setValue?.(v);
|
|
2412
|
+
fieldCtx?.setTextInside?.(true);
|
|
2413
|
+
} else {
|
|
2414
|
+
fieldCtx?.setTextInside?.(false);
|
|
2415
|
+
}
|
|
2416
|
+
} else if (customProps.text) {
|
|
2417
|
+
const v = customProps.text();
|
|
2418
|
+
fieldCtx?.setTextInside?.(!(v === undefined || v === null || v.trim() === ''));
|
|
2419
|
+
}
|
|
2365
2420
|
});
|
|
2366
|
-
//
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2421
|
+
// React to programmatic FormGroup.set changes
|
|
2422
|
+
createEffect(() => {
|
|
2423
|
+
if (formName && formCtx?.data) {
|
|
2424
|
+
const v = formCtx.data[formName];
|
|
2425
|
+
// keep internal state aligned if unmanaged
|
|
2426
|
+
if (!customProps.text && internal() !== v) setInternal(String(v ?? ''));
|
|
2427
|
+
if (fieldCtx) {
|
|
2428
|
+
const has = !(v === undefined || v === null || typeof v === 'string' && v.trim() === '');
|
|
2429
|
+
fieldCtx.setTextInside(has);
|
|
2430
|
+
fieldCtx.setValue?.(v);
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2370
2433
|
});
|
|
2434
|
+
// Resize whenever value changes (user or programmatic)
|
|
2371
2435
|
createEffect(() => {
|
|
2372
|
-
|
|
2373
|
-
|
|
2436
|
+
areaValue();
|
|
2437
|
+
queueMicrotask(resizeToContent);
|
|
2438
|
+
});
|
|
2439
|
+
const handleInput = e => {
|
|
2440
|
+
const newVal = e.currentTarget.value;
|
|
2441
|
+
// Update whichever source is active
|
|
2442
|
+
if (formName && formCtx?.formGroup) {
|
|
2443
|
+
formCtx.formGroup.set(formName, newVal);
|
|
2444
|
+
formCtx.setData?.(formName, newVal);
|
|
2445
|
+
} else if (customProps.setText) {
|
|
2446
|
+
customProps.setText(newVal);
|
|
2374
2447
|
} else {
|
|
2375
|
-
|
|
2448
|
+
setInternal(newVal);
|
|
2376
2449
|
}
|
|
2377
|
-
|
|
2450
|
+
if (fieldCtx) {
|
|
2451
|
+
fieldCtx.setValue?.(newVal);
|
|
2452
|
+
fieldCtx.setTextInside?.(newVal.trim().length > 0);
|
|
2453
|
+
}
|
|
2454
|
+
resizeToContent();
|
|
2455
|
+
};
|
|
2378
2456
|
return (() => {
|
|
2379
2457
|
var _el$ = _tmpl$$e();
|
|
2380
2458
|
use(el => {
|
|
2381
2459
|
myElement = el;
|
|
2382
|
-
|
|
2460
|
+
resizeToContent();
|
|
2383
2461
|
}, _el$);
|
|
2384
2462
|
spread(_el$, mergeProps(normalProps, {
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
context?.setFocused(true);
|
|
2388
|
-
}
|
|
2389
|
-
},
|
|
2390
|
-
"onBlur": e => {
|
|
2391
|
-
if (context?.setFocused) {
|
|
2392
|
-
context?.setFocused(false);
|
|
2393
|
-
}
|
|
2394
|
-
},
|
|
2395
|
-
get placeholder() {
|
|
2396
|
-
return !!context?.getName && context?.getTextInside() && !context?.getFocused() ? "" : props.placeholder;
|
|
2463
|
+
get value() {
|
|
2464
|
+
return areaValue();
|
|
2397
2465
|
},
|
|
2398
2466
|
get ["class"]() {
|
|
2399
|
-
return `${style$4.areaStyle} ${customProps.class ??
|
|
2400
|
-
},
|
|
2401
|
-
get value() {
|
|
2402
|
-
return customProps.text();
|
|
2467
|
+
return `${style$4.areaStyle} ${customProps.class ?? ''} ${customProps.transparent ? customProps.transparent : ''}`;
|
|
2403
2468
|
},
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
OnInput();
|
|
2407
|
-
if (!!context?.getName && !!e.currentTarget.value.trim()) {
|
|
2408
|
-
context?.setValue(e.currentTarget.value);
|
|
2409
|
-
context?.setTextInside(true);
|
|
2410
|
-
} else if (!!context?.getName && !e.currentTarget.value.trim()) {
|
|
2411
|
-
context?.setValue("");
|
|
2412
|
-
context?.setTextInside(false);
|
|
2413
|
-
}
|
|
2469
|
+
get placeholder() {
|
|
2470
|
+
return fieldCtx?.getTextInside?.() && !fieldCtx?.getFocused?.() ? '' : props.placeholder;
|
|
2414
2471
|
},
|
|
2415
2472
|
get title() {
|
|
2416
2473
|
return customProps.tooltip;
|
|
2417
|
-
}
|
|
2474
|
+
},
|
|
2475
|
+
"onInput": handleInput,
|
|
2476
|
+
"onFocus": () => fieldCtx?.setFocused?.(true),
|
|
2477
|
+
"onBlur": () => fieldCtx?.setFocused?.(false)
|
|
2418
2478
|
}), false, false);
|
|
2419
2479
|
return _el$;
|
|
2420
2480
|
})();
|
|
@@ -3834,6 +3894,13 @@ class FormGroup {
|
|
|
3834
3894
|
this.validators = newValidators;
|
|
3835
3895
|
this.errors = createSignal(newErrors);
|
|
3836
3896
|
}
|
|
3897
|
+
/**
|
|
3898
|
+
* INTERNAL: returns the reactive internal store reference (DO NOT MUTATE outside FormGroup).
|
|
3899
|
+
* Used for bridging into FormContext without triggering cloning loops.
|
|
3900
|
+
*/
|
|
3901
|
+
_unsafeRaw() {
|
|
3902
|
+
return this.internalDataSignal[0];
|
|
3903
|
+
}
|
|
3837
3904
|
get(key) {
|
|
3838
3905
|
if (!key) {
|
|
3839
3906
|
// Custom clone that preserves FormArray instances (structuredClone fails on functions inside)
|