contain-css-svelte 1.1.19 → 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.
Files changed (94) hide show
  1. package/dist/Card.svelte +22 -8
  2. package/dist/Card.svelte.d.ts +4 -5
  3. package/dist/controls/Button.svelte +19 -5
  4. package/dist/controls/Button.svelte.d.ts +4 -4
  5. package/dist/controls/ButtonLink.svelte +17 -14
  6. package/dist/controls/ButtonLink.svelte.d.ts +4 -4
  7. package/dist/controls/Checkbox.svelte +15 -8
  8. package/dist/controls/Checkbox.svelte.d.ts +4 -4
  9. package/dist/controls/CircleButton.svelte +14 -7
  10. package/dist/controls/CircleButton.svelte.d.ts +4 -4
  11. package/dist/controls/Input.svelte +14 -3
  12. package/dist/controls/Input.svelte.d.ts +4 -3
  13. package/dist/controls/Option.svelte +4 -3
  14. package/dist/controls/Option.svelte.d.ts +3 -2
  15. package/dist/controls/RadioButton.svelte +14 -7
  16. package/dist/controls/RadioButton.svelte.d.ts +4 -4
  17. package/dist/controls/Select.svelte +15 -3
  18. package/dist/controls/Select.svelte.d.ts +4 -3
  19. package/dist/controls/Slider.svelte +5 -11
  20. package/dist/controls/Slider.svelte.d.ts +3 -3
  21. package/dist/controls/TabItem.svelte +24 -5
  22. package/dist/controls/TabItem.svelte.d.ts +4 -4
  23. package/dist/controls/Toggle.svelte +21 -5
  24. package/dist/controls/Toggle.svelte.d.ts +4 -4
  25. package/dist/dropdowns/DropdownMenu.svelte +18 -6
  26. package/dist/dropdowns/DropdownMenu.svelte.d.ts +4 -4
  27. package/dist/layout/Accordion.svelte +17 -2
  28. package/dist/layout/Accordion.svelte.d.ts +5 -3
  29. package/dist/layout/Bar.svelte +27 -15
  30. package/dist/layout/Bar.svelte.d.ts +4 -4
  31. package/dist/layout/Column.svelte.d.ts +3 -3
  32. package/dist/layout/ColumnContainer.svelte +12 -9
  33. package/dist/layout/ColumnContainer.svelte.d.ts +4 -4
  34. package/dist/layout/Columns.svelte +4 -3
  35. package/dist/layout/Columns.svelte.d.ts +7 -3
  36. package/dist/layout/Container.svelte +23 -8
  37. package/dist/layout/Container.svelte.d.ts +7 -5
  38. package/dist/layout/DataList.svelte +15 -7
  39. package/dist/layout/DataList.svelte.d.ts +5 -4
  40. package/dist/layout/DataListItem.svelte +14 -8
  41. package/dist/layout/DataListItem.svelte.d.ts +4 -4
  42. package/dist/layout/Fieldset.svelte +16 -8
  43. package/dist/layout/Fieldset.svelte.d.ts +6 -3
  44. package/dist/layout/Form.svelte +17 -8
  45. package/dist/layout/Form.svelte.d.ts +8 -6
  46. package/dist/layout/FormItem.svelte +12 -7
  47. package/dist/layout/FormItem.svelte.d.ts +4 -3
  48. package/dist/layout/FormProvider.svelte +3 -0
  49. package/dist/layout/GridLayout.svelte +14 -9
  50. package/dist/layout/GridLayout.svelte.d.ts +4 -4
  51. package/dist/layout/GridRow.svelte +6 -10
  52. package/dist/layout/GridRow.svelte.d.ts +3 -2
  53. package/dist/layout/Hero.svelte +14 -8
  54. package/dist/layout/Hero.svelte.d.ts +4 -4
  55. package/dist/layout/Inline.svelte +16 -15
  56. package/dist/layout/Inline.svelte.d.ts +4 -4
  57. package/dist/layout/MenuList.svelte +13 -6
  58. package/dist/layout/MenuList.svelte.d.ts +4 -4
  59. package/dist/layout/Page.svelte +14 -8
  60. package/dist/layout/Page.svelte.d.ts +11 -3
  61. package/dist/layout/ResponsiveText.svelte +4 -0
  62. package/dist/layout/Row.svelte.d.ts +3 -3
  63. package/dist/layout/RowContainer.svelte +12 -9
  64. package/dist/layout/RowContainer.svelte.d.ts +4 -4
  65. package/dist/layout/Sidebar.svelte +17 -6
  66. package/dist/layout/Sidebar.svelte.d.ts +12 -4
  67. package/dist/layout/SplitPane.svelte +8 -14
  68. package/dist/layout/SplitPane.svelte.d.ts +16 -2
  69. package/dist/layout/Stack.svelte +16 -15
  70. package/dist/layout/Stack.svelte.d.ts +4 -4
  71. package/dist/layout/TabBar.svelte +12 -2
  72. package/dist/layout/TabBar.svelte.d.ts +17 -10
  73. package/dist/layout/Table.svelte +5 -1
  74. package/dist/layout/Tile.svelte +40 -27
  75. package/dist/layout/Tile.svelte.d.ts +32 -10
  76. package/dist/misc/Code.svelte +2 -0
  77. package/dist/misc/Progress.svelte +25 -8
  78. package/dist/misc/Progress.svelte.d.ts +15 -8
  79. package/dist/misc/Tag.svelte +97 -44
  80. package/dist/misc/Tag.svelte.d.ts +17 -5
  81. package/dist/overlays/Dialog.svelte +18 -5
  82. package/dist/overlays/Dialog.svelte.d.ts +5 -3
  83. package/dist/overlays/Tooltip.svelte +21 -3
  84. package/dist/overlays/Tooltip.svelte.d.ts +5 -3
  85. package/dist/styleProps.d.ts +67 -0
  86. package/dist/styleProps.js +76 -0
  87. package/dist/types.d.ts +40 -1
  88. package/dist/types.js +1 -1
  89. package/dist/typography/Text.svelte +4 -11
  90. package/dist/typography/TextLayout.svelte +4 -7
  91. package/dist/typography/TextLayout.svelte.d.ts +4 -3
  92. package/dist/util.d.ts +60 -3
  93. package/dist/util.js +101 -11
  94. package/package.json +1 -1
package/dist/util.d.ts CHANGED
@@ -1,4 +1,61 @@
1
- export declare function injectVars(props: {
2
- [key: string]: any;
3
- }, prefix: string, varList: string[]): string;
1
+ /**
2
+ * Split a component's rest props into a `style` string and the attributes that
3
+ * belong on an element, keeping the two separate.
4
+ *
5
+ * Use this for a component that renders a wrapper around a control (Toggle,
6
+ * RadioButton, Checkbox, FormItem): the CSS variables and the caller's `style`
7
+ * belong on the wrapper, because that is what the component's own CSS targets
8
+ * and what a caller expects to position, while `aria-*`, `name`, `required`
9
+ * and `data-*` belong on the control itself. {@link elementProps} is the
10
+ * single-element case and is what most components want.
11
+ *
12
+ * @returns `style` for the wrapper, `attrs` (never containing `style`) for the
13
+ * control.
14
+ */
15
+ export declare function splitProps(props: Record<string, any>, prefix: string, varList?: readonly string[], extraVars?: string): {
16
+ style: string;
17
+ attrs: Record<string, unknown>;
18
+ };
19
+ /**
20
+ * Split a component's rest props into the attributes that belong on its root
21
+ * element, with the component's CSS variables and the caller's own `style`
22
+ * merged into a single `style` attribute.
23
+ *
24
+ * This is the one place the library's attribute pass-through contract lives.
25
+ * It exists because spreading raw rest props gets three things wrong at once:
26
+ *
27
+ * 1. **Style props leaked as attributes.** `bg`, `fg`, `padding` and friends are
28
+ * read for their CSS variables but were then spread too, rendering invalid
29
+ * `<button bg="red">`. Names in `varList` are consumed here, never emitted.
30
+ * 2. **The caller's `style` clobbered the variables.** `<Tag bg="red" style="margin:0">`
31
+ * dropped `--tag-bg` entirely, because the spread's `style` overwrote the
32
+ * component's. Both are concatenated instead, caller last so their
33
+ * declarations win without erasing the variables.
34
+ * 3. **Custom properties leaked as attributes.** A spread `{"--tag-bg": "red"}`
35
+ * rendered a literal `--tag-bg="red"` attribute. They become declarations.
36
+ *
37
+ * `class` is deliberately NOT handled here. Merging it in the template as
38
+ * `class={["tag", className]}` keeps the component's own class literal in the
39
+ * markup, which is what lets the compiler's CSS pruning see that `.tag` is used.
40
+ *
41
+ * @param props - the component's rest props. Pass style props that were
42
+ * destructured out back in explicitly (`{ bg, fg, ...restProps }`) or their
43
+ * variables will not be emitted.
44
+ * @param prefix - CSS variable prefix, e.g. `"tag"` for `--tag-bg`
45
+ * @param varList - prop names to convert into `--prefix-name` declarations
46
+ * @param extraVars - variables the component computes itself, e.g.
47
+ * `--slider-percent`. Placed after the prop variables and before the
48
+ * caller's `style`, so a caller can still override it.
49
+ *
50
+ * @example
51
+ * const el = $derived(elementProps(restProps, "tag", ["bg", "fg", "padding"]));
52
+ * // <span class={["tag", className]} class:primary {...el}>
53
+ */
54
+ export declare function elementProps(props: Record<string, any>, prefix: string, varList?: readonly string[], extraVars?: string): Record<string, unknown>;
55
+ /**
56
+ * Build only the CSS variable string, for a component that has no element to
57
+ * spread attributes onto (Dialog, which portals its content and copies
58
+ * variables across).
59
+ */
60
+ export declare function injectVars(props: Record<string, any>, prefix: string, varList: readonly string[]): string;
4
61
  export declare function copyCSSVariables(origin: HTMLElement, target: HTMLElement, variableList?: string[]): void;
package/dist/util.js CHANGED
@@ -1,19 +1,109 @@
1
1
  import { cssProperties } from "./cssprops";
2
- export function injectVars(props, prefix, varList) {
2
+ /**
3
+ * Build the `--prefix-name` CSS variable declarations for a component.
4
+ *
5
+ * Kept separate from {@link elementProps} only so a component that composes its
6
+ * style string by hand (Dialog, which also copies variables across a portal)
7
+ * can reuse the naming rules. Prefer `elementProps` everywhere else.
8
+ */
9
+ function buildVars(props, prefix, varList) {
3
10
  let cssVars = "";
4
- varList.forEach((v) => {
5
- if (props[v]) {
6
- const cssVarName = toKebabCase(v);
7
- cssVars += `--${prefix}-${cssVarName}: ${props[v]};`;
8
- }
9
- });
10
- for (let prop in props) {
11
- if (prop[0] == "-" && prop[1] == "-") {
12
- cssVars += `${prop}: ${props[prop]};`;
13
- }
11
+ for (const name of varList) {
12
+ const value = props[name];
13
+ // `0` is a meaningful length, so it is NOT skipped -- the old `if (value)`
14
+ // test dropped it. `false` still is: Form and Fieldset type `border` as
15
+ // `string | boolean`, where `false` means "no border", not the declaration
16
+ // `--form-border: false`.
17
+ if (value == null || value === "" || value === false)
18
+ continue;
19
+ cssVars += `--${prefix}-${toKebabCase(name)}: ${value};`;
20
+ }
21
+ for (const key in props) {
22
+ // Custom properties arriving via an object spread -- see CssVarProps.
23
+ if (key.startsWith("--"))
24
+ cssVars += `${key}: ${props[key]};`;
14
25
  }
15
26
  return cssVars;
16
27
  }
28
+ /**
29
+ * Split a component's rest props into a `style` string and the attributes that
30
+ * belong on an element, keeping the two separate.
31
+ *
32
+ * Use this for a component that renders a wrapper around a control (Toggle,
33
+ * RadioButton, Checkbox, FormItem): the CSS variables and the caller's `style`
34
+ * belong on the wrapper, because that is what the component's own CSS targets
35
+ * and what a caller expects to position, while `aria-*`, `name`, `required`
36
+ * and `data-*` belong on the control itself. {@link elementProps} is the
37
+ * single-element case and is what most components want.
38
+ *
39
+ * @returns `style` for the wrapper, `attrs` (never containing `style`) for the
40
+ * control.
41
+ */
42
+ export function splitProps(props, prefix, varList = [], extraVars = "") {
43
+ const attrs = {};
44
+ for (const key in props) {
45
+ if (key.startsWith("--"))
46
+ continue; // becomes a declaration, not an attribute
47
+ if (key === "style")
48
+ continue; // returned separately
49
+ if (varList.includes(key))
50
+ continue; // a style prop, not an attribute
51
+ attrs[key] = props[key];
52
+ }
53
+ return {
54
+ style: buildVars(props, prefix, varList) + extraVars + (props.style ?? ""),
55
+ attrs,
56
+ };
57
+ }
58
+ /**
59
+ * Split a component's rest props into the attributes that belong on its root
60
+ * element, with the component's CSS variables and the caller's own `style`
61
+ * merged into a single `style` attribute.
62
+ *
63
+ * This is the one place the library's attribute pass-through contract lives.
64
+ * It exists because spreading raw rest props gets three things wrong at once:
65
+ *
66
+ * 1. **Style props leaked as attributes.** `bg`, `fg`, `padding` and friends are
67
+ * read for their CSS variables but were then spread too, rendering invalid
68
+ * `<button bg="red">`. Names in `varList` are consumed here, never emitted.
69
+ * 2. **The caller's `style` clobbered the variables.** `<Tag bg="red" style="margin:0">`
70
+ * dropped `--tag-bg` entirely, because the spread's `style` overwrote the
71
+ * component's. Both are concatenated instead, caller last so their
72
+ * declarations win without erasing the variables.
73
+ * 3. **Custom properties leaked as attributes.** A spread `{"--tag-bg": "red"}`
74
+ * rendered a literal `--tag-bg="red"` attribute. They become declarations.
75
+ *
76
+ * `class` is deliberately NOT handled here. Merging it in the template as
77
+ * `class={["tag", className]}` keeps the component's own class literal in the
78
+ * markup, which is what lets the compiler's CSS pruning see that `.tag` is used.
79
+ *
80
+ * @param props - the component's rest props. Pass style props that were
81
+ * destructured out back in explicitly (`{ bg, fg, ...restProps }`) or their
82
+ * variables will not be emitted.
83
+ * @param prefix - CSS variable prefix, e.g. `"tag"` for `--tag-bg`
84
+ * @param varList - prop names to convert into `--prefix-name` declarations
85
+ * @param extraVars - variables the component computes itself, e.g.
86
+ * `--slider-percent`. Placed after the prop variables and before the
87
+ * caller's `style`, so a caller can still override it.
88
+ *
89
+ * @example
90
+ * const el = $derived(elementProps(restProps, "tag", ["bg", "fg", "padding"]));
91
+ * // <span class={["tag", className]} class:primary {...el}>
92
+ */
93
+ export function elementProps(props, prefix, varList = [], extraVars = "") {
94
+ const { style, attrs } = splitProps(props, prefix, varList, extraVars);
95
+ if (style)
96
+ attrs.style = style;
97
+ return attrs;
98
+ }
99
+ /**
100
+ * Build only the CSS variable string, for a component that has no element to
101
+ * spread attributes onto (Dialog, which portals its content and copies
102
+ * variables across).
103
+ */
104
+ export function injectVars(props, prefix, varList) {
105
+ return buildVars(props, prefix, varList);
106
+ }
17
107
  function toKebabCase(str) {
18
108
  return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
19
109
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contain-css-svelte",
3
- "version": "1.1.19",
3
+ "version": "1.2.0",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "capture:review": "node scripts/capture-review.mjs",