@innovaccer/design-system 4.26.1 → 4.28.0-1

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 (39) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/css/SCOPED_CSS.md +145 -0
  3. package/css/dist/index.css +36 -14
  4. package/css/dist/index.css.map +1 -1
  5. package/css/dist/mds-scoped.css +13826 -0
  6. package/css/gulpfile.js +34 -25
  7. package/css/scoped/package.json +5 -0
  8. package/css/scripts/build-scoped.mjs +313 -0
  9. package/css/scripts/css-sources.cjs +49 -0
  10. package/css/scripts/portal-roots.cjs +47 -0
  11. package/css/src/components/calendar.module.css +3 -4
  12. package/css/src/components/grid.module.css +18 -6
  13. package/css/src/components/horizontalNav.module.css +11 -0
  14. package/css/src/components/spinner.module.css +4 -4
  15. package/dist/brotli/index.js +1 -1
  16. package/dist/brotli/index.js.br +0 -0
  17. package/dist/cjs/index.js +1 -1
  18. package/dist/core/components/atoms/dropdown/DropdownButton.d.ts +1 -0
  19. package/dist/core/components/atoms/input/Input.d.ts +1 -0
  20. package/dist/core/components/organisms/calendar/Calendar.d.ts +2 -0
  21. package/dist/core/components/organisms/calendar/utils.d.ts +5 -0
  22. package/dist/core/components/organisms/datePicker/DatePicker.d.ts +4 -0
  23. package/dist/core/components/organisms/datePicker/Trigger.d.ts +2 -0
  24. package/dist/core/components/organisms/dateRangePicker/DateRangePicker.d.ts +8 -0
  25. package/dist/core/components/organisms/dateRangePicker/SingleInputTrigger.d.ts +2 -0
  26. package/dist/core/components/organisms/dateRangePicker/Trigger.d.ts +6 -0
  27. package/dist/core/components/organisms/grid/columnUtility.d.ts +1 -1
  28. package/dist/core/components/organisms/select/Select.d.ts +2 -0
  29. package/dist/core/components/organisms/select/SelectOption.d.ts +1 -0
  30. package/dist/core/components/organisms/select/SelectTrigger.d.ts +2 -0
  31. package/dist/esm/index.js +744 -375
  32. package/dist/gzip/index.js +1 -1
  33. package/dist/gzip/index.js.gz +0 -0
  34. package/dist/index.js +609 -289
  35. package/dist/index.js.map +1 -1
  36. package/dist/index.umd.css +36 -14
  37. package/dist/index.umd.js +1 -1
  38. package/dist/types/tsconfig.type.tsbuildinfo +43 -39
  39. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -1,3 +1,61 @@
1
+ ## 4.28.0-1 (2026-08-18)
2
+
3
+ ### Highlights
4
+
5
+ - Support for scoped CSS, letting consumers isolate design-system styles from the host application's global stylesheet.
6
+
7
+ ### Breaking changes
8
+
9
+ NA
10
+
11
+ ### Migration guide
12
+
13
+ NA
14
+
15
+ ### Deprecations
16
+
17
+ NA
18
+
19
+ ### Improvements
20
+
21
+ - style(css): add support for scoped css (fcedea2d5)
22
+
23
+ ---
24
+
25
+ ## 4.27.0 (2026-08-04)
26
+
27
+ ### Highlights
28
+
29
+ - Full keyboard navigation in the Calendar component, plus a broad sweep of ARIA and semantic-structure fixes across Dropdown, Select, Table, HorizontalNav, and Icon.
30
+
31
+ ### Breaking changes
32
+
33
+ NA
34
+
35
+ ### Migration guide
36
+
37
+ NA
38
+
39
+ ### Deprecations
40
+
41
+ NA
42
+
43
+ ### Features
44
+
45
+ - feat(calendar): add keyboard navigation in calendar component (d548c7824)
46
+
47
+ ### Fixes
48
+
49
+ - fix(dropdown): add a11y attribute in dropdown component (36213a930)
50
+ - fix(horizontalNav): fix a11y list structure of nav items (5f0a26b6e)
51
+ - fix(table): update a11y attributes in draggable dropdown (2d782a127)
52
+ - fix(icon): add aria attributes for decorative icon (6984f1d93)
53
+ - fix(table): update target size of resize drag element (5b7ba50e5)
54
+ - fix(select): add aria attributes in select component (4a61bbe25)
55
+ - fix(stories): update accessibility relates issues (5284d8aff)
56
+
57
+ ---
58
+
1
59
  ## 4.26.0 (2026-07-14)
2
60
 
3
61
  ### Highlights
@@ -0,0 +1,145 @@
1
+ # Scoped stylesheet
2
+
3
+ An additional consumer entry built alongside the default `dist/index.css`. Identical rules,
4
+ wrapped in `@scope ([data-mds-root])`, so MDS styles only apply inside containers the host
5
+ app opts in to — useful when MDS runs next to another stylesheet (Tailwind, a legacy global
6
+ sheet, another design system) in the same document.
7
+
8
+ - Output: `css/dist/mds-scoped.css`
9
+ - Import: `@innovaccer/design-system/css/scoped` or `…/css/dist/mds-scoped.css`
10
+ - Build: `npm run build-css` (gulp, builds both bundles) or `npm run build-css-scoped`
11
+
12
+ The default `dist/index.css` bundle is unchanged — this is purely additive.
13
+
14
+ ## Usage
15
+
16
+ ```html
17
+ <div data-mds-root>
18
+ <!-- MDS components -->
19
+ </div>
20
+ ```
21
+
22
+ Everything outside `[data-mds-root]` is untouched by MDS, and MDS components inside it are
23
+ unaffected by the host app's global styles that would otherwise reach them.
24
+
25
+ The scope root is yours to style — MDS declares nothing on it. If you put `data-mds-root` on a
26
+ custom element, remember that custom elements default to `display: inline`, so give it a
27
+ `display` of its own:
28
+
29
+ ```css
30
+ ui-shell-app {
31
+ display: block;
32
+ }
33
+ ```
34
+
35
+ ## How the build composes it
36
+
37
+ `scripts/build-scoped.mjs` reads the same sources, in the same order, as the default build
38
+ (both import the list from `scripts/css-sources.cjs`, so they cannot drift), then:
39
+
40
+ 1. **Hoists global-namespace at-rules** — `@keyframes`, `@font-face`, `@property` and
41
+ `@counter-style` above the `@scope` block. Their names are document-global and are not
42
+ scopable; leaving them inside would silently drop them. The build throws if one is nested
43
+ inside another at-rule, where the hoist cannot reach it.
44
+ 2. **Remaps `:root` / `html` / `body` / `:host` to `:scope`** so design tokens attach to the
45
+ scope root. Without this, every custom-property reference in the bundle resolves to nothing.
46
+ 3. **Adds a root-anchored variant of every selector** — `.Backdrop` becomes
47
+ `.Backdrop, :scope.Backdrop`. See *Overlays* below.
48
+ 4. **Wraps the result** in `@scope ([data-mds-root]) { … }`.
49
+
50
+ Step 3 costs about +28% in raw bytes (~80 KB, considerably less gzipped).
51
+
52
+ Nothing is declared on the scope root itself. A `[data-mds-root]` element is consumer
53
+ markup, so any default MDS set there would compete with the consumer's own layout.
54
+
55
+ ## Overlays
56
+
57
+ Modal, Sidesheet, FullscreenModal, Backdrop, Popover, Tooltip, Dropdown, Menu and the
58
+ Listbox drag ghost all render through `ReactDOM.createPortal` into `document.body` — outside
59
+ the consumer's `[data-mds-root]`. Without special handling they would receive neither
60
+ component rules nor tokens, and render completely unstyled.
61
+
62
+ Inside `@scope`, a rule like `.Backdrop` is implicitly `:scope .Backdrop`, so it matches
63
+ **descendants of a scope root only**. Those portaled elements therefore have to be scope
64
+ roots in their own right, and there is no MDS-owned ancestor to hang that on. So the build
65
+ adds them to the prelude directly, targeting markup the components *already* render:
66
+
67
+ ```css
68
+ @scope (
69
+ [data-mds-root], /* your opt-in container */
70
+ body > .Overlay-wrapper:has([data-layer]), /* Modal, Sidesheet, FullscreenModal */
71
+ body > [data-test='DesignSystem-Popover'], /* Popover, Tooltip, Dropdown, Menu, … */
72
+ body > [data-test='DesignSystem-Backdrop'], /* Backdrop */
73
+ body > .Listbox-item--draggable /* Listbox drag ghost */
74
+ )
75
+ ```
76
+
77
+ Every popper-based component shares one root — `Popover` renders the popup element itself and
78
+ Tooltip/Dropdown/Menu all go through it — so a single selector covers them all.
79
+
80
+ Each selector is qualified so it cannot collide with a host app's own class names:
81
+
82
+ - **`body >`** — all of these land as direct children of `<body>`, so a colliding host class
83
+ would have to be at body level too.
84
+ - **`:has([data-layer])`** — `data-layer` is an MDS-only attribute present on all five portal
85
+ roots. `.Overlay-wrapper` is a generic enough name that a host app could plausibly reuse it,
86
+ so the class alone is not enough. It matches a *descendant* rather than a child because Modal
87
+ wraps its container in `OutsideClick` when `backdropClose` is set.
88
+ - **`data-test='DesignSystem-*'`** — already namespaced.
89
+
90
+ The root-anchored selector variants from step 3 are what let those roots style *themselves*:
91
+ `.Backdrop` alone would only match descendants. Because *every* rule gets a variant, all rules
92
+ matching a given scope root are bumped by the same `:scope` (0,1,0), so relative specificity —
93
+ and therefore the cascade between MDS rules — is preserved.
94
+
95
+ `css/scripts/portal-roots.cjs` is the single source of truth for this list, shared with
96
+ `core/utils/__tests__/scopedPortalRoots.test.tsx`. That test renders each overlay and asserts
97
+ the selectors still match, so if a component ever stops rendering one of these hooks the build
98
+ fails loudly instead of silently shipping unstyled overlays.
99
+
100
+ ### No component changes required
101
+
102
+ This is the reason the prelude keys off existing markup rather than a dedicated attribute:
103
+ nothing in `core/` changes, so **the scoped stylesheet can be updated independently of the
104
+ library version**. Consumers swap the CSS file without rebuilding or upgrading, and it works
105
+ against releases already in the wild.
106
+
107
+ ## Custom scope selectors
108
+
109
+ `@scope`'s prelude is a forgiving selector list, so attribute and class patterns work:
110
+
111
+ ```bash
112
+ MDS_SCOPE_SELECTOR='[data-mds-root], [class^="ui-"][class$="-app"]' npm run build-css-scoped
113
+ MDS_SCOPE_OUTPUT='ui-apps.css' MDS_SCOPE_SELECTOR='ui-shell-app, ui-admin-app' npm run build-css-scoped
114
+ ```
115
+
116
+ One selector list in a single `@scope` block covers many hosts — you do not need a stylesheet
117
+ per app.
118
+
119
+ `MDS_SCOPE_SELECTOR` replaces only the *consumer* part of the prelude. The portal-root
120
+ selectors are always appended, so MDS's overlays stay scoped whatever you scope on. The build
121
+ logs the final prelude it used.
122
+
123
+ CSS has **no tag-name wildcard**, so a pattern like `ui-*-app` cannot be expressed as a
124
+ selector: `^=` / `$=` / `*=` match attribute *values*, and a tag name is not an attribute.
125
+ For custom elements following a naming convention, either enumerate the tags in
126
+ `MDS_SCOPE_SELECTOR`, or have the host stamp `data-mds-root` onto matching elements at
127
+ runtime (a `MutationObserver` plus `/^ui-.*-app$/.test(el.tagName.toLowerCase())`).
128
+
129
+ ## Caveats
130
+
131
+ - **Browser support**: `@scope` requires Chrome/Edge 118+, Safari 17.4+, Firefox 128+. There
132
+ is no fallback — an older browser drops the whole stylesheet as an unknown at-rule and
133
+ renders MDS unstyled. Serve `dist/index.css` to browsers you still support.
134
+ - **`@keyframes` names stay global.** They are hoisted out of `@scope`, so animation names
135
+ still collide with the host app's. `Spinner`'s were renamed to `mds-spin` / `mds-rotate`;
136
+ generic ones such as `fadeIn`, `fadeOut` and `shimmer` remain exposed.
137
+ - **Portaled overlays get base tokens**, not per-root token overrides: a themed
138
+ `[data-mds-root]` does not affect overlays, which are scope roots of their own under
139
+ `<body>`. They are deliberately not re-parented into the app's scope root, because a
140
+ `transform` / `filter` / `contain` on an ancestor there would become the containing block
141
+ and break `position: fixed` overlays. Declare token overrides on `:root` so both the
142
+ in-tree components and the body-level overlays pick them up.
143
+ - **The drag ghost has the weakest qualifier.** No `data-test` exists on it, so
144
+ `body > .Listbox-item--draggable` is all that is available. Worth tightening with a
145
+ `data-test` next time component changes ship.
@@ -2732,15 +2732,14 @@ body {
2732
2732
  color: inherit;
2733
2733
  }
2734
2734
 
2735
+ /* Always show focus on calendar cells: open-via-click moves focus programmatically
2736
+ (mouse modality → :focus-visible is false), and roving tabindex needs a visible target. */
2737
+ .Calendar-value:focus,
2735
2738
  .Calendar-value:focus-visible {
2736
2739
  outline: var(--border-width-05) solid var(--primary-focus);
2737
2740
  outline-offset: 1px;
2738
2741
  }
2739
2742
 
2740
- .Calendar-value:focus:not(:focus-visible) {
2741
- outline: none;
2742
- }
2743
-
2744
2743
  .Calendar-value:hover {
2745
2744
  background: var(--secondary-light);
2746
2745
  border-color: var(--secondary-dark);
@@ -5790,13 +5789,25 @@ body {
5790
5789
 
5791
5790
  .Grid-cellResize {
5792
5791
  position: absolute;
5792
+ top: 0;
5793
5793
  right: 0;
5794
- width: var(--spacing-10);
5794
+ width: var(--spacing-60);
5795
+ height: 100%;
5795
5796
  cursor: ew-resize;
5797
+ box-sizing: border-box;
5798
+ }
5799
+
5800
+ .Grid-cellResize::after {
5801
+ content: '';
5802
+ position: absolute;
5803
+ top: 0;
5804
+ right: 0;
5805
+ width: var(--spacing-10);
5796
5806
  height: 100%;
5797
- padding-right: var(--spacing-60);
5798
- margin-right: calc(-1 * var(--spacing-60));
5799
- box-sizing: content-box;
5807
+ }
5808
+
5809
+ .Grid-headCell:has(> .Grid-cellResize) {
5810
+ padding-right: calc(var(--spacing-60) - var(--spacing-10));
5800
5811
  }
5801
5812
 
5802
5813
  .Grid-cellSortIcon {
@@ -5809,12 +5820,12 @@ body {
5809
5820
  background: var(--secondary);
5810
5821
  }
5811
5822
 
5812
- .Grid-cellResize:hover {
5823
+ .Grid-cellResize:hover::after,
5824
+ .Grid-cellResize:focus-visible::after {
5813
5825
  background: var(--primary);
5814
5826
  }
5815
5827
 
5816
5828
  .Grid-cellResize:focus-visible {
5817
- background: var(--primary);
5818
5829
  outline: none;
5819
5830
  }
5820
5831
 
@@ -6201,6 +6212,17 @@ body {
6201
6212
  display: flex;
6202
6213
  }
6203
6214
 
6215
+ .HorizontalNav-list {
6216
+ display: flex;
6217
+ list-style: none;
6218
+ margin: 0;
6219
+ padding: 0;
6220
+ }
6221
+
6222
+ .HorizontalNav-listItem {
6223
+ display: flex;
6224
+ }
6225
+
6204
6226
  .HorizontalNav-menu {
6205
6227
  box-sizing: border-box;
6206
6228
  display: flex;
@@ -10087,7 +10109,7 @@ body {
10087
10109
  }
10088
10110
  }
10089
10111
 
10090
- @keyframes rotate {
10112
+ @keyframes mds-rotate {
10091
10113
  0% {
10092
10114
  transform: rotate(0deg);
10093
10115
  }
@@ -10096,7 +10118,7 @@ body {
10096
10118
  }
10097
10119
  }
10098
10120
 
10099
- @keyframes spin {
10121
+ @keyframes mds-spin {
10100
10122
  0% {
10101
10123
  stroke-dasharray: 1, 200;
10102
10124
  stroke-dashoffset: 0;
@@ -10112,7 +10134,7 @@ body {
10112
10134
  }
10113
10135
 
10114
10136
  .Spinner {
10115
- animation: rotate 2s linear infinite;
10137
+ animation: mds-rotate 2s linear infinite;
10116
10138
  }
10117
10139
 
10118
10140
  .Spinner--xsmall {
@@ -10139,7 +10161,7 @@ body {
10139
10161
  stroke-linecap: round;
10140
10162
  stroke-dasharray: 1 200;
10141
10163
  stroke-dashoffset: 0;
10142
- animation: spin 1.5s ease-in-out infinite;
10164
+ animation: mds-spin 1.5s ease-in-out infinite;
10143
10165
  }
10144
10166
 
10145
10167
  .Circle--primary {