cetec-design-system 2.2.2-next.0 → 2.3.7

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 (36) hide show
  1. package/dist/{cetec-preset-CcvrY8wh.js → cetec-preset-CZJA5UR0.js} +1696 -1331
  2. package/dist/cetec-preset-CZJA5UR0.js.map +1 -0
  3. package/dist/index.js +12655 -9360
  4. package/dist/index.js.map +1 -1
  5. package/dist/panda.buildinfo.json +461 -365
  6. package/dist/playroom-static.css +68887 -180258
  7. package/dist/preset.js +1 -1
  8. package/dist/specs/recipes.json +126 -25
  9. package/dist/styles.css +1315 -642
  10. package/dist/types/index.d.ts +3001 -273
  11. package/dist/types/preset.d.ts +15 -0
  12. package/package.json +6 -1
  13. package/src/recipes/autocomplete.ts +266 -0
  14. package/src/recipes/calendar.ts +92 -0
  15. package/src/recipes/chip.ts +6 -0
  16. package/src/recipes/dateMenus.ts +40 -0
  17. package/src/recipes/dateTimeMenus.ts +43 -0
  18. package/src/recipes/menu.ts +13 -1
  19. package/src/recipes/modal.ts +1 -1
  20. package/src/recipes/recipes-slot.ts +7 -2
  21. package/src/recipes/segmentedFields.ts +192 -0
  22. package/src/recipes/segmentedInputs.ts +106 -0
  23. package/src/recipes/text.ts +32 -28
  24. package/src/recipes/timeMenus.ts +110 -0
  25. package/src/styles/primitives/zIndex.ts +1 -0
  26. package/src/styles/semantics/colors.ts +44 -0
  27. package/src/styles/semantics/zIndex.ts +2 -0
  28. package/src/styles/utilities/conditions.ts +1 -0
  29. package/src/styles/utilities/transitions.ts +2 -1
  30. package/src/utils/dsChain.ts +113 -0
  31. package/src/utils/dsComponent.ts +44 -0
  32. package/src/utils/dsPart.ts +41 -0
  33. package/src/utils/splitProps.ts +15 -0
  34. package/dist/cetec-preset-CcvrY8wh.js.map +0 -1
  35. package/src/recipes/datePicker.ts +0 -230
  36. package/src/recipes/timePicker.ts +0 -206
@@ -0,0 +1,113 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ /**
4
+ * Attribute name that carries a resolved interaction chain on a portal root.
5
+ * Always lowercase and hyphenated; HTML lowercases attribute names, so a
6
+ * camelCase spelling would silently produce a different attribute.
7
+ */
8
+ export const DS_CHAIN_ATTRIBUTE = 'data-ds-chain';
9
+
10
+ /** Separator written between chain nodes in the serialized attribute value. */
11
+ export const DS_CHAIN_SEPARATOR = '>';
12
+
13
+ /**
14
+ * Attribute marking the wrapper a portal's contents render into. Written
15
+ * unconditionally, including when the resolved chain is empty, so a consumer
16
+ * walking up the DOM can tell a portal boundary from an ordinary element and
17
+ * stop there instead of continuing into `document.body`.
18
+ */
19
+ export const DS_PORTAL_ROOT_ATTRIBUTE = 'data-ds-portal-root';
20
+
21
+ /**
22
+ * Maximum number of chain nodes retained. The nearest nodes are kept because
23
+ * the leaf end of the chain is what identifies an interaction; page-level
24
+ * object identity is carried separately rather than through this chain.
25
+ */
26
+ export const DS_CHAIN_MAX_DEPTH = 5;
27
+
28
+ /**
29
+ * Attribute carrying business-object identity. The application authors it — on
30
+ * a layout wrapper for legacy Perl screens, on individual elements on React
31
+ * screens. The design system never invents a value; it only copies one onto a
32
+ * portal root, which is the single place DOM ancestry cannot supply it.
33
+ */
34
+ export const DS_OBJECT_ATTRIBUTE = 'data-track-object';
35
+
36
+ // Module-level constant so every reader outside a scope shares one identity.
37
+ // A fresh `[]` default would hand consumers a new value on each render and
38
+ // defeat the memoization in the provider.
39
+ const EMPTY_CHAIN: readonly string[] = Object.freeze([]);
40
+
41
+ /**
42
+ * Carries the `data-testid` values of the enclosing tagged elements, nearest
43
+ * last. React context walks the React tree rather than the DOM, so portaled
44
+ * content still resolves the chain of the subtree that rendered it.
45
+ */
46
+ export const DsChainContext = createContext<readonly string[]>(EMPTY_CHAIN);
47
+
48
+ /**
49
+ * Returns the interaction chain for the current position in the React tree.
50
+ *
51
+ * Returns a shared empty array outside any scope, so the result is safe to read
52
+ * unconditionally.
53
+ */
54
+ export const useDsChain = (): readonly string[] => useContext(DsChainContext);
55
+
56
+ /**
57
+ * Appends a `data-testid` value to a chain, keeping the nearest
58
+ * `DS_CHAIN_MAX_DEPTH` nodes.
59
+ *
60
+ * A value equal to the innermost node is dropped rather than repeated. Two
61
+ * supported arrangements produce that case: a component that opens a scope
62
+ * above its root and also writes the same id on an inner element, and a
63
+ * consumer that wraps a design-system component in `DsChainScope` using the
64
+ * `data-testid` that component already emits. Neither is an error, and a
65
+ * repeated node carries no information while it consumes one of five slots.
66
+ *
67
+ * Only the innermost node is compared. A legitimately recurring id further out
68
+ * — a nested grid inside a grid — still contributes, because the repeat there
69
+ * describes real structure.
70
+ */
71
+ export const extendDsChain = (
72
+ chain: readonly string[],
73
+ testId: string,
74
+ ): readonly string[] => {
75
+ if (chain[chain.length - 1] === testId) return chain;
76
+
77
+ const next = [...chain, testId];
78
+
79
+ return next.length > DS_CHAIN_MAX_DEPTH
80
+ ? next.slice(-DS_CHAIN_MAX_DEPTH)
81
+ : next;
82
+ };
83
+
84
+ /**
85
+ * Serializes a chain for the `data-ds-chain` attribute.
86
+ *
87
+ * Returns `undefined` for an empty chain so React omits the attribute instead
88
+ * of emitting an empty string that consumers would have to special-case.
89
+ */
90
+ export const dsChainValue = (chain: readonly string[]): string | undefined =>
91
+ chain.length > 0 ? chain.join(DS_CHAIN_SEPARATOR) : undefined;
92
+
93
+ /**
94
+ * Resolves the business object governing `element` by walking up the DOM to the
95
+ * nearest ancestor carrying `DS_OBJECT_ATTRIBUTE`, `element` itself included.
96
+ *
97
+ * Nearest wins. A legacy Perl screen tags one layout wrapper, so every element
98
+ * on it resolves to the same object; a React screen tags individual elements,
99
+ * so an interaction resolves to the region it started in rather than to the
100
+ * page. Both fall out of the same walk.
101
+ *
102
+ * Returns `undefined` when no ancestor is tagged — including for an element
103
+ * that is not in the document, and for an empty attribute value — so React
104
+ * omits the attribute instead of emitting an empty string that a consumer would
105
+ * have to special-case. An untagged screen must produce no answer, never a
106
+ * borrowed one.
107
+ */
108
+ export const dsObjectValue = (
109
+ element: Element | null | undefined,
110
+ ): string | undefined =>
111
+ element
112
+ ?.closest(`[${DS_OBJECT_ATTRIBUTE}]`)
113
+ ?.getAttribute(DS_OBJECT_ATTRIBUTE) || undefined;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Attribute name that identifies which design-system component rendered a DOM
3
+ * element. Always lowercase and hyphenated; HTML lowercases attribute names, so
4
+ * a camelCase spelling would silently produce a different attribute.
5
+ */
6
+ export const DS_COMPONENT_ATTRIBUTE = 'data-ds-component';
7
+
8
+ /** Attribute record applied to a design-system component's root element. */
9
+ export type DsComponentAttribute = {
10
+ 'data-ds-component': string;
11
+ };
12
+
13
+ /**
14
+ * Returns the `data-ds-component` attribute for a component's root element.
15
+ *
16
+ * Spread the result as the first attribute on the root element so a
17
+ * consumer-supplied `data-ds-component` in the component's rest props still
18
+ * wins. When rest props are forwarded to a nested element instead of the root,
19
+ * pull `data-ds-component` out of the props first and pass it as `override` so
20
+ * the explicit value lands on the root and does not leak onto the inner
21
+ * element.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * // Rest props are spread on the root: ordering handles the override.
26
+ * <Box {...dsComponent('Badge')} className={classes.root} {...otherProps} />
27
+ * ```
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * // Rest props are forwarded to a nested control: pass the override through.
32
+ * const { 'data-ds-component': dsComponentName, ...rest } = props;
33
+ *
34
+ * <Box {...dsComponent('Checkbox', dsComponentName)}>
35
+ * <Box as="input" {...otherProps} />
36
+ * </Box>;
37
+ * ```
38
+ */
39
+ export const dsComponent = (
40
+ name: string,
41
+ override?: string,
42
+ ): DsComponentAttribute => ({
43
+ [DS_COMPONENT_ATTRIBUTE]: override ?? name,
44
+ });
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Attribute name that names an interactive part inside a design-system
3
+ * component. Always lowercase and hyphenated; HTML lowercases attribute names,
4
+ * so a camelCase spelling would silently produce a different attribute.
5
+ */
6
+ export const DS_PART_ATTRIBUTE = 'data-ds-part';
7
+
8
+ /** Attribute record applied to a named part of a design-system component. */
9
+ export type DsPartAttribute = {
10
+ 'data-ds-part': string;
11
+ };
12
+
13
+ /**
14
+ * Returns the `data-ds-part` attribute for a named part of a component.
15
+ *
16
+ * Internal instrumentation with the same status as `data-ds-component`: emitted
17
+ * automatically, not a supported public API, and not part of any prop type.
18
+ * **It is not a test handle** — tests query by role, or by the `data-testid` a
19
+ * consumer supplied. Do not document it, type it, or reference it from a test
20
+ * outside this repository.
21
+ *
22
+ * It exists for the collector, which needs to tell apart the interactive parts
23
+ * of one component: a click on a `Select`'s trigger is a different event from a
24
+ * click on a chip's remove control inside it, and both report the same
25
+ * `data-ds-component` and the same chain. The part name is what separates them,
26
+ * and it is the DS's to assign because only the DS knows its own anatomy.
27
+ *
28
+ * Spread the result before the component's rest props so a consumer-supplied
29
+ * value in rest props still wins, matching `dsComponent`.
30
+ *
31
+ * The chain mechanism reads `data-testid` only (see `Box` and
32
+ * `~/utils/dsChain`), so this attribute never contributes a chain node.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * <Box role="combobox" {...dsPart('trigger')} {...triggerProps} />
37
+ * ```
38
+ */
39
+ export const dsPart = (part: string): DsPartAttribute => ({
40
+ [DS_PART_ATTRIBUTE]: part,
41
+ });
@@ -1,8 +1,23 @@
1
1
  import { css, cx } from '@styled-system/css';
2
2
  import { splitCssProps } from '@styled-system/jsx';
3
3
 
4
+ /** Record of native attributes and Panda CSS properties accepted by `splitProps`. */
4
5
  type PropsRecord = Record<string, unknown>;
5
6
 
7
+ /**
8
+ * Separates Panda CSS props from remaining element props and returns a merged
9
+ * class name for the generated styles.
10
+ *
11
+ * The first tuple value combines an existing string `className` with styles
12
+ * generated from Panda CSS props, including the `css` prop. The second value
13
+ * excludes those styling props and `className`, so it can be spread onto an
14
+ * element without leaking them to the DOM.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * const [className, elementProps] = splitProps({ p: '4', id: 'profile' });
19
+ * ```
20
+ */
6
21
  export const splitProps = (props: PropsRecord): [string, PropsRecord] => {
7
22
  const [cssProps, otherProps] = splitCssProps(props);
8
23
  const { css: cssProp, ...styleProps } = cssProps;