@odx/foundation 1.0.0-rc.4 → 1.0.0-rc.6

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/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## 1.0.0-rc.6
2
+
3
+ ### Minor Changes
4
+
5
+ - Rename CSS layers to remove dot notation:
6
+ - `odx.reset` to `odx-reset`
7
+ - `odx.base` to `odx-base`
8
+ - `odx.overrides` to `odx-overrides`
9
+
10
+ ### Bug Fixes
11
+
12
+ - Remove debug info from rolldown build output
13
+ - Fix `.odx-cloak` if applied to `:root` element not working correctly
14
+
15
+ ## 1.0.0-rc.5
16
+
17
+ ### Major Changes
18
+
19
+ - Rename CSS utility classes `odx-text-primary|accent|...` to `odx-fg-*` to better reflect their purpose
20
+
21
+ ### Minor Changes
22
+
23
+ - Add `.odx-cloak` class to prevent FOUC (Flash of Unstyled Content) during initial load, use `odx-cloak` class on the root element of your application to enable it.
24
+ - Support `:visited` state for native links and anchors with `odx-link` class for better user experience
25
+ - Improve tabbable element detection
26
+
1
27
  ## 1.0.0-rc.4
2
28
 
3
29
  ### Bug Fixes
package/README.md CHANGED
@@ -86,6 +86,18 @@ setTheme({
86
86
  });
87
87
  ```
88
88
 
89
+ ### Page Cloak
90
+
91
+ To prevent unstyled content from flashing during the initial load of your application, you can use the `.odx-cloak` CSS class.
92
+ This class will temporarily hide the content of the `.odx-root` element until custom elements are fully loaded.
93
+
94
+ ```html
95
+ <html class="odx-root odx-cloak">
96
+ </html>
97
+ ```
98
+
99
+ > The timeout can be set via the `--odx-cloak-timeout` custom property on the `:root` element, which defaults to `2s`.
100
+
89
101
  ### Documentation
90
102
 
91
- For detailed documentation on how to use the `@odx/foundation` package, including examples and best practices, please visit our <a href="https://ca-odx-storybook-dev.yellowisland-7b13f2d7.westeurope.azurecontainerapps.io/" target="_blank" rel="noopener">storybook documentation</a>.
103
+ For detailed documentation on how to use the `@odx/foundation` package, please visit our <a href="https://ca-odx-storybook-dev.yellowisland-7b13f2d7.westeurope.azurecontainerapps.io/" target="_blank" rel="noopener">storybook documentation</a>.
@@ -1,6 +1,4 @@
1
1
  import { Signal } from "./signals.js";
2
-
3
- //#region src/lib/breakpoints.d.ts
4
2
  declare global {
5
3
  namespace ODX.Breakpoints {
6
4
  interface Config {
@@ -57,5 +55,4 @@ declare function setupBreakpoints(breakpointsConfig?: BreakpointConfig[]): () =>
57
55
  declare function createBreakpointUpdater(breakpoints: Breakpoint[], update?: (target: HTMLElement, change: Breakpoint & {
58
56
  matches: boolean;
59
57
  }) => void): () => void;
60
- //#endregion
61
58
  export { Breakpoint, BreakpointConfig, BreakpointOperator, breakpointAttribute, buildBreakpoint, createBreakpointUpdater, defaultBreakpoints, expandBreakpoints, observeBreakpoint, registeredBreakpoints, setupBreakpoints };
@@ -1,6 +1,5 @@
1
1
  import { effect, signal } from "./signals.js";
2
2
  import { observeMedia } from "./utils/shared-media-observer.js";
3
- //#region src/lib/breakpoints.ts
4
3
  const operators = [
5
4
  "<",
6
5
  "<=",
@@ -154,5 +153,4 @@ function createBreakpointUpdater(breakpoints, update) {
154
153
  }
155
154
  };
156
155
  }
157
- //#endregion
158
156
  export { breakpointAttribute, buildBreakpoint, createBreakpointUpdater, defaultBreakpoints, expandBreakpoints, observeBreakpoint, registeredBreakpoints, setupBreakpoints };
@@ -1,6 +1,4 @@
1
1
  import { UnitIdentifier } from "./models.js";
2
-
3
- //#region src/lib/format.d.ts
4
2
  interface FormatOptions {
5
3
  dateTimeFormatOptions?: DateTimeFormatOptions;
6
4
  numberFormatOptions?: NumberFormatOptions;
@@ -53,7 +51,7 @@ declare const TIME_UNIT_MAP: {
53
51
  };
54
52
  interface RelativeTimeFormatOptions extends Intl.RelativeTimeFormatOptions, BaseFormatOptions {
55
53
  minUnit?: keyof typeof TIME_UNIT_MAP;
54
+ start?: number | string | Date;
56
55
  }
57
56
  declare function formatRelativeTime(input: number | string | Date, options?: RelativeTimeFormatOptions): string;
58
- //#endregion
59
57
  export { DateTimeFormatOptions, FormatOptions, ListFormatOptions, NumberFormatOptions, RelativeTimeFormatOptions, formatDate, formatList, formatNumber, formatRelativeTime, parseDate };
@@ -1,4 +1,3 @@
1
- //#region src/lib/format.ts
2
1
  function parseDate(value) {
3
2
  const createDate = (value) => Number.isNaN(value) ? null : new Date(value);
4
3
  if (value instanceof Date) return createDate(value.getTime());
@@ -54,12 +53,12 @@ const TIME_UNIT_MAP = {
54
53
  }
55
54
  };
56
55
  function formatRelativeTime(input, options) {
56
+ const startDate = parseDate(options?.start ?? Date.now());
57
57
  const value = parseDate(input);
58
- if (!value) return "";
59
- const relativeTime = value.getTime() - Date.now();
58
+ if (!value || !startDate) return "";
59
+ const relativeTime = value.getTime() - startDate.getTime();
60
60
  const minUnit = options?.minUnit && TIME_UNIT_MAP[options.minUnit] || TIME_UNIT_MAP.second;
61
61
  const [unit, unitConfig] = Object.entries(TIME_UNIT_MAP).find(([_, { value, max }]) => Math.abs(relativeTime) < max && minUnit.value <= value);
62
62
  return new Intl.RelativeTimeFormat(options?.locale, options).format(Math.round(relativeTime / unitConfig.value), unit);
63
63
  }
64
- //#endregion
65
64
  export { formatDate, formatList, formatNumber, formatRelativeTime, parseDate };
@@ -1,6 +1,4 @@
1
1
  import { FormatOptions } from "./format.js";
2
-
3
- //#region src/lib/localization.d.ts
4
2
  interface LocalizationOptions extends FormatOptions {
5
3
  defaultLocale: () => Intl.Locale | Intl.UnicodeBCP47LocaleIdentifier;
6
4
  fallbackLanguage: () => Intl.UnicodeBCP47LocaleIdentifier;
@@ -11,5 +9,4 @@ declare function setLocalizationOptions(options?: Partial<LocalizationOptions> |
11
9
  declare function getLocalizationOptions(options?: Partial<LocalizationOptions> | null): LocalizationOptions;
12
10
  declare function getLocale(localeInput?: Intl.Locale | Intl.UnicodeBCP47LocaleIdentifier | null): Intl.Locale;
13
11
  declare function setLocale(localeInput?: Intl.Locale | Intl.UnicodeBCP47LocaleIdentifier | null): void;
14
- //#endregion
15
12
  export { LocalizationOptions, getLocale, getLocalizationOptions, setLocale, setLocalizationOptions };
@@ -1,5 +1,4 @@
1
1
  import { sharedSignal } from "./signals.js";
2
- //#region src/lib/localization.ts
3
2
  const locale = sharedSignal("locale", null);
4
3
  const localizationOptions = sharedSignal("localizationOptions", null);
5
4
  const LocalizationOptions = (config) => ({
@@ -24,5 +23,4 @@ function getLocale(localeInput) {
24
23
  function setLocale(localeInput) {
25
24
  locale.set(localeInput ? getLocale(localeInput) : null);
26
25
  }
27
- //#endregion
28
26
  export { LocalizationOptions, getLocale, getLocalizationOptions, setLocale, setLocalizationOptions };
@@ -1,5 +1,3 @@
1
- //#region src/lib/models.d.ts
2
1
  type UnitIdentifier = SingleUnitIdentifier | `${SingleUnitIdentifier}-per-${SingleUnitIdentifier}` | (string & {});
3
2
  type SingleUnitIdentifier = 'acre' | 'bit' | 'byte' | 'celsius' | 'centimeter' | 'day' | 'degree' | 'fahrenheit' | 'fluid-ounce' | 'foot' | 'gallon' | 'gigabit' | 'gigabyte' | 'gram' | 'hectare' | 'hour' | 'inch' | 'kilobit' | 'kilobyte' | 'kilogram' | 'kilometer' | 'liter' | 'megabit' | 'megabyte' | 'meter' | 'microsecond' | 'mile' | 'mile-scandinavian' | 'milliliter' | 'millimeter' | 'millisecond' | 'minute' | 'month' | 'nanosecond' | 'ounce' | 'percent' | 'petabyte' | 'pound' | 'second' | 'stone' | 'terabit' | 'terabyte' | 'week' | 'yard' | 'year';
4
- //#endregion
5
3
  export { UnitIdentifier };
@@ -1,6 +1,4 @@
1
1
  import { Signal } from "signal-polyfill";
2
-
3
- //#region src/lib/signals.d.ts
4
2
  type Signal$1<T> = Signal.State<T> & {
5
3
  update: (updateFn: (value: T) => T) => void;
6
4
  };
@@ -19,5 +17,4 @@ declare function effect(callback: (() => void) | (() => () => void)): () => void
19
17
  declare global {
20
18
  var __ODX_SHARED_SIGNALS__: Record<string, unknown>;
21
19
  }
22
- //#endregion
23
20
  export { ReadonlySignal, Signal$1 as Signal, SignalOptions, computed, effect, sharedSignal, signal };
@@ -1,5 +1,4 @@
1
1
  import { Signal } from "signal-polyfill";
2
- //#region src/lib/signals.ts
3
2
  function transformOptions(options) {
4
3
  if (!options) return;
5
4
  return {
@@ -48,5 +47,4 @@ function effect(callback) {
48
47
  };
49
48
  }
50
49
  globalThis.__ODX_SHARED_SIGNALS__ ||= {};
51
- //#endregion
52
50
  export { computed, effect, sharedSignal, signal };
@@ -1,6 +1,4 @@
1
1
  import { ThemeConfig } from "@odx/design-tokens";
2
-
3
- //#region src/lib/theming.d.ts
4
2
  declare global {
5
3
  var __ODX_THEME_ROOT__: HTMLElement;
6
4
  }
@@ -15,5 +13,4 @@ interface AttachDarkModeToggleOptions<T extends HTMLElement> {
15
13
  root?: HTMLElement;
16
14
  }
17
15
  declare function attachDarkModeToggle<T extends HTMLElement>(host: T, options?: AttachDarkModeToggleOptions<T>): () => void;
18
- //#endregion
19
16
  export { AttachDarkModeToggleOptions, attachDarkModeToggle, darkModeIcon, isDarkModeEnabled, lightModeIcon, setTheme$1 as setTheme, toggleDarkMode, userPrefersDarkMode };
@@ -1,6 +1,5 @@
1
1
  import { effect, sharedSignal } from "./signals.js";
2
2
  import { darkModeClass, lightModeClass, setTheme } from "@odx/design-tokens";
3
- //#region src/lib/theming.ts
4
3
  const { matches: userPrefersDarkMode = false } = globalThis.matchMedia?.("(prefers-color-scheme: dark)") ?? {};
5
4
  const darkModeIcon = "core::night-mode";
6
5
  const lightModeIcon = "core::brightness";
@@ -30,5 +29,4 @@ function attachDarkModeToggle(host, options = {}) {
30
29
  options.update?.(host, darkModeEnabled, icon);
31
30
  });
32
31
  }
33
- //#endregion
34
32
  export { attachDarkModeToggle, darkModeIcon, isDarkModeEnabled, lightModeIcon, setTheme$1 as setTheme, toggleDarkMode, userPrefersDarkMode };
@@ -1,4 +1,3 @@
1
- //#region src/lib/utils/shared-media-observer.ts
2
1
  const mediaQueryRegistry = /* @__PURE__ */ new Map();
3
2
  const eventListenerRegistry = /* @__PURE__ */ new Map();
4
3
  function handleMediaChange(event) {
@@ -37,5 +36,4 @@ function unobserveMedia(query, listener) {
37
36
  mediaQueryList.removeEventListener("change", handleMediaChange);
38
37
  mediaQueryRegistry.delete(query);
39
38
  }
40
- //#endregion
41
39
  export { observeMedia };
package/dist/styles.css CHANGED
@@ -1,4 +1,4 @@
1
- @layer odx.reset {
1
+ @layer odx-reset {
2
2
  .odx-root {
3
3
  &, & *, & :before, & :after {
4
4
  box-sizing: border-box;
@@ -62,48 +62,114 @@
62
62
  }
63
63
  }
64
64
 
65
- @layer odx.base {
66
- .odx-slot-placeholder-sm, .odx-slot-placeholder {
67
- background-color: var(--odx-color-background-accent-subtle);
68
- padding: var(--odx-spacing-layout-sm) var(--odx-spacing-layout-lg);
69
- width: 100%;
70
- height: 100%;
71
- min-height: var(--odx-control-height-md);
72
- text-align: center;
73
- text-overflow: ellipsis;
74
- pointer-events: none;
75
- user-select: none;
76
- flex: 1;
77
- place-content: center;
78
- overflow: hidden;
65
+ @layer odx-base {
66
+ .odx-link, .odx-root a {
67
+ transition: var(--odx-motion-transition-reduced);
68
+ overflow: inherit;
69
+ vertical-align: baseline;
70
+ text-align: start;
71
+ text-decoration: initial;
72
+ text-overflow: inherit;
73
+ color: var(--odx-color-foreground-accent-rest);
74
+ cursor: pointer;
75
+ user-select: text;
76
+ border-radius: 1px;
77
+ outline: 0;
78
+ font-family: inherit;
79
+ font-size: 1em;
80
+ transition-property: color;
81
+ display: inline-block;
79
82
 
80
- &:before, &:after {
81
- display: block;
83
+ &:active {
84
+ color: var(--odx-color-foreground-accent-pressed);
82
85
  }
83
86
 
84
- &:before {
85
- text-transform: capitalize;
86
- font-size: var(--odx-typography-font-size-text-sm);
87
- font-weight: var(--odx-typography-font-weight-medium);
88
- content: attr(slot, "default") " slot";
87
+ &:focus-visible {
88
+ outline: var(--odx-focus-ring-outer);
89
+ outline-offset: var(--odx-focus-ring-offset-sm);
89
90
  }
90
91
 
91
- &:after {
92
- line-height: var(--odx-typography-line-height-text-xs);
93
- color: var(--odx-color-foreground-subtle);
94
- font-size: var(--odx-typography-font-size-text-xs);
95
- content: "This is a placeholder. A Replace with your own content";
92
+ &:visited {
93
+ color: var(--odx-color-special-link-visited);
94
+ }
95
+
96
+ &[disabled] {
97
+ color: var(--odx-color-foreground-disabled-rest);
98
+ pointer-events: none;
99
+ user-select: none;
100
+ }
101
+
102
+ @media (hover: hover) {
103
+ &:hover:not([disabled], :active, :focus-visible) {
104
+ color: var(--odx-color-foreground-accent-hover);
105
+ text-decoration: underline;
106
+ }
96
107
  }
97
108
  }
98
109
 
99
- .odx-slot-placeholder-sm {
100
- padding: var(--odx-spacing-12) var(--odx-spacing-layout-sm);
101
- min-height: var(--odx-control-addon-size-md);
102
- font-size: var(--odx-typography-font-size-text-sm);
110
+ :root {
111
+ interpolate-size: allow-keywords;
112
+ }
113
+
114
+ .odx-root {
115
+ transition: opacity var(--odx-motion-duration-slow) linear;
116
+ tab-size: 4;
117
+ line-height: var(--odx-typography-line-height-base);
118
+ color: var(--odx-color-foreground-rest);
119
+ font-family: var(--odx-typography-font-family-base), "Noto Sans", Kanit, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji";
120
+ font-size: var(--odx-typography-font-size-base);
121
+ text-size-adjust: 100%;
122
+ -webkit-tap-highlight-color: transparent;
123
+ scrollbar-width: thin;
124
+
125
+ &[inert] {
126
+ opacity: 0;
127
+ transition-duration: 0s;
128
+ }
129
+ }
130
+
131
+ html.odx-root {
132
+ scroll-behavior: smooth;
133
+ scrollbar-color: var(--odx-color-special-scrollbar) transparent;
134
+ height: 100%;
103
135
 
104
- &:after {
105
- display: none;
136
+ &:not(:has(body.odx-light-mode), :has(body.odx-dark-mode)) {
137
+ background-color: var(--odx-color-background-base);
106
138
  }
139
+
140
+ & body {
141
+ margin: 0;
142
+ padding: 0;
143
+ }
144
+ }
145
+
146
+ :root {
147
+ --odx-cloak-timeout: 2s;
148
+ }
149
+
150
+ .odx-cloak:has(:not(:defined)) > * {
151
+ animation: var(--odx-cloak-timeout) step-end odx-cloak-hide;
152
+ }
153
+
154
+ @keyframes odx-cloak-hide {
155
+ from {
156
+ opacity: 0;
157
+ }
158
+
159
+ to {
160
+ opacity: 1;
161
+ }
162
+ }
163
+
164
+ .odx-visually-hidden:not(:focus-within), .odx-visually-hidden-force {
165
+ clip-path: rect(0 0 0 0) !important;
166
+ white-space: nowrap !important;
167
+ border: none !important;
168
+ width: 1px !important;
169
+ height: 1px !important;
170
+ padding: 0 !important;
171
+ position: absolute !important;
172
+ overflow: hidden !important;
107
173
  }
108
174
 
109
175
  .odx-cluster, .odx-flank, .odx-stack {
@@ -137,16 +203,52 @@
137
203
  flex: none;
138
204
  }
139
205
 
140
- .odx-align-baseline, .odx-align-start {
206
+ :where(.odx-align-baseline, .odx-align-start, .odx-align-center, .odx-align-end, .odx-align-stretch) {
207
+ display: flex;
208
+ }
209
+
210
+ .odx-align-baseline {
211
+ align-items: baseline;
212
+ }
213
+
214
+ .odx-align-self-baseline {
215
+ align-self: baseline;
216
+ }
217
+
218
+ .odx-align-start {
141
219
  align-items: flex-start;
142
220
  }
143
221
 
222
+ .odx-align-self-start {
223
+ align-self: flex-start;
224
+ }
225
+
144
226
  .odx-align-center {
145
227
  align-items: center;
146
228
  }
147
229
 
230
+ .odx-align-self-center {
231
+ align-self: center;
232
+ }
233
+
148
234
  .odx-align-end {
149
- align-items: end;
235
+ align-items: flex-end;
236
+ }
237
+
238
+ .odx-align-self-end {
239
+ align-self: flex-end;
240
+ }
241
+
242
+ .odx-align-stretch {
243
+ align-items: stretch;
244
+ }
245
+
246
+ .odx-align-self-stretch {
247
+ align-self: stretch;
248
+ }
249
+
250
+ :where(.odx-justify-start, .odx-justify-end, .odx-justify-center, .odx-justify-space-between, .odx-justify-space-around, .odx-justify-space-evenly) {
251
+ display: flex;
150
252
  }
151
253
 
152
254
  .odx-justify-start {
@@ -161,22 +263,34 @@
161
263
  justify-content: center;
162
264
  }
163
265
 
164
- .odx-justify-space-between {
165
- justify-content: space-between;
166
- }
167
-
168
266
  .odx-justify-space-around {
169
267
  justify-content: space-around;
170
268
  }
171
269
 
270
+ .odx-justify-space-between {
271
+ justify-content: space-between;
272
+ }
273
+
172
274
  .odx-justify-space-evenly {
173
275
  justify-content: space-evenly;
174
276
  }
175
277
 
278
+ :where(.odx-nowrap, .odx-wrap, .odx-wrap-reverse) {
279
+ display: flex;
280
+ }
281
+
176
282
  .odx-nowrap {
177
283
  flex-wrap: nowrap;
178
284
  }
179
285
 
286
+ .odx-wrap {
287
+ flex-wrap: wrap;
288
+ }
289
+
290
+ .odx-wrap-reverse {
291
+ flex-wrap: wrap-reverse;
292
+ }
293
+
180
294
  [class*="odx-auto-grid"] {
181
295
  --max-columns: 6;
182
296
  --min-column-size: 250px;
@@ -194,227 +308,10 @@
194
308
  grid-template-columns: repeat(auto-fill, var(--_column-size));
195
309
  }
196
310
 
197
- .odx-content :where(table), .odx-table {
198
- --cell-size: var(--odx-size-300);
199
- border-collapse: collapse;
200
- background-color: #0000;
201
- width: 100%;
202
- max-width: 100%;
203
-
204
- & caption {
205
- line-height: var(--odx-typography-line-height-text-sm);
206
- font-size: var(--odx-typography-font-size-text-sm);
207
- font-weight: var(--odx-typography-font-weight-semibold);
208
- }
209
-
210
- & thead {
211
- background-color: inherit;
212
- }
213
-
214
- & tr {
215
- transition: var(--odx-motion-transition-reduced);
216
- background-color: var(--odx-color-background-transparent);
217
- transition-property: background-color, color;
218
- }
219
-
220
- & tr:has(td):hover {
221
- background-color: var(--odx-color-background-transparent-hover);
222
- }
223
-
224
- & th, & td {
225
- padding: var(--odx-control-spacing-md) var(--odx-control-spacing-inline-md);
226
- min-height: var(--odx-size-250);
227
- text-align: start;
228
- font-size: inherit;
229
- }
230
-
231
- & th {
232
- border-bottom: var(--odx-border-width-thin) solid var(--odx-color-stroke-neutral-subtle);
233
- vertical-align: top;
234
- font-weight: var(--odx-typography-font-weight-medium);
235
- cursor: default;
236
- user-select: none;
237
- }
238
-
239
- & td {
240
- height: var(--cell-size);
241
- vertical-align: middle;
242
- }
243
-
244
- & tr:not(:last-child) td {
245
- border-bottom: var(--odx-border-width-thin) solid var(--odx-color-stroke-neutral-subtle);
246
- }
247
-
248
- & th :is(odx-input, odx-select) {
249
- margin-inline: var(--odx-spacing-negative-50);
250
- }
251
- }
252
-
253
- .odx-content {
254
- --_content-spacing-sm: var(--odx-spacing-layout-sm);
255
- --_content-spacing-md: var(--odx-spacing-layout-md);
256
- --_content-spacing-lg: var(--odx-spacing-layout-lg);
257
- line-height: var(--odx-typography-line-height-text-md);
258
-
259
- & table, & ul, & ol, & dl, & blockquote, & pre, & figure, & video, & embed, & iframe {
260
- margin: var(--_content-spacing-md) 0;
261
- }
262
-
263
- & :is(odx-key-value-list, odx-list) {
264
- margin-block: var(--_content-spacing-md);
265
-
266
- & :is(odx-key-value-list, odx-list) {
267
- margin-block: 0;
268
- }
269
- }
270
-
271
- & > :is(odx-text, .odx-text), & li > :is(ul, ol, dl), & p, & li {
272
- margin: var(--_content-spacing-sm) 0;
273
- }
274
-
275
- & :is(odx-text, .odx-text), & p {
276
- &:first-child {
277
- margin-block-start: 0;
278
- }
279
- }
280
-
281
- & > :is(odx-title, [class*="odx-title"]), & h1, & h2, & h3, & h4, & h5, & h6 {
282
- margin-block: var(--_content-spacing-lg) var(--_content-spacing-sm);
283
-
284
- &:first-child {
285
- margin-block-start: var(--_content-spacing-sm);
286
- }
287
- }
288
-
289
- & table, & ul, & ol, & dl, & blockquote {
290
- padding-inline-start: var(--odx-spacing-150);
291
- }
292
-
293
- & code, & pre, & mark {
294
- border-radius: var(--odx-border-radius-sm);
295
- padding: 0 var(--odx-spacing-12);
296
- }
297
-
298
- & code, & pre {
299
- background-color: var(--odx-color-background-control-rest);
300
- font-size: var(--odx-typography-font-size-text-sm);
301
- }
302
-
303
- & blockquote {
304
- padding-inline-end: var(--odx-spacing-150);
305
- }
306
-
307
- & dt {
308
- font-weight: var(--odx-typography-font-weight-medium);
309
- }
310
-
311
- & a {
312
- text-decoration: underline;
313
- }
314
-
315
- & del {
316
- color: var(--odx-color-foreground-danger-rest);
317
- }
318
-
319
- & figure {
320
- flex-direction: column;
321
- display: flex;
322
- }
323
-
324
- & figcaption {
325
- padding: var(--_content-spacing-sm);
326
- line-height: var(--odx-typography-line-height-text-sm);
327
- font-size: var(--odx-typography-font-size-text-sm);
328
- }
329
-
330
- & ins {
331
- color: var(--odx-color-foreground-success-rest);
332
- text-decoration: none;
333
- }
334
-
335
- & mark {
336
- background-color: var(--odx-color-background-selection);
337
- color: var(--odx-color-foreground-rest);
338
- }
339
-
340
- & pre {
341
- padding: var(--odx-control-spacing-md) calc(2 * var(--odx-control-spacing-inline-md));
342
- }
343
-
344
- & small {
345
- font-size: var(--odx-typography-font-size-text-sm);
346
- }
347
-
348
- & var {
349
- font-weight: var(--odx-typography-font-weight-medium);
350
- }
351
- }
352
-
353
- .odx-content-sm {
354
- --_content-spacing-md: var(--odx-spacing-layout-sm);
355
- --_content-spacing-lg: var(--odx-spacing-layout-md);
356
- line-height: var(--odx-typography-line-height-text-sm);
357
- font-size: var(--odx-typography-font-size-text-sm);
358
- }
359
-
360
- .odx-content-box {
361
- background-color: var(--odx-color-background-level-1);
362
- padding: var(--odx-spacing-layout-lg);
363
- border-radius: 0;
364
- }
365
-
366
- .odx-link, .odx-root a {
367
- transition: var(--odx-motion-transition-reduced);
368
- overflow: inherit;
369
- vertical-align: baseline;
370
- text-align: start;
371
- text-decoration: initial;
372
- text-overflow: inherit;
373
- color: var(--odx-color-foreground-accent-rest);
374
- cursor: pointer;
375
- user-select: text;
376
- border-radius: 1px;
377
- outline: 0;
378
- font-family: inherit;
379
- font-size: 1em;
380
- transition-property: color;
381
- display: inline-block;
382
-
383
- &:active {
384
- color: var(--odx-color-foreground-accent-pressed);
385
- }
386
-
387
- &:focus-visible {
388
- outline: var(--odx-focus-ring-outer);
389
- outline-offset: var(--odx-focus-ring-offset-sm);
390
- }
391
-
392
- &[disabled] {
393
- color: var(--odx-color-foreground-disabled-rest);
394
- pointer-events: none;
395
- user-select: none;
396
- }
397
-
398
- @media (hover: hover) {
399
- &:hover:not([disabled], :active, :focus-visible) {
400
- color: var(--odx-color-foreground-accent-hover);
401
- text-decoration: underline;
402
- }
403
- }
404
- }
405
-
406
- .odx-text {
407
- overflow-wrap: break-word;
311
+ [class*="odx-text"] {
312
+ line-height: var(--odx-typography-line-height-base);
313
+ font-family: var(--odx-typography-font-family-base);
408
314
  font-weight: var(--odx-typography-font-weight-normal);
409
- display: block;
410
- }
411
-
412
- .odx-text-inline {
413
- display: inline-block;
414
- }
415
-
416
- .odx-text-strong {
417
- font-weight: var(--odx-typography-font-weight-medium);
418
315
  }
419
316
 
420
317
  .odx-text-xs {
@@ -437,35 +334,14 @@
437
334
  font-size: var(--odx-typography-font-size-text-lg);
438
335
  }
439
336
 
440
- .odx-text-neutral {
441
- color: var(--odx-color-foreground-rest);
442
- }
443
-
444
- .odx-text-accent {
445
- color: var(--odx-color-foreground-accent-rest);
446
- }
447
-
448
- .odx-text-success {
449
- color: var(--odx-color-foreground-success-rest);
450
- }
451
-
452
- .odx-text-danger {
453
- color: var(--odx-color-foreground-danger-rest);
454
- }
455
-
456
- .odx-text-subtle {
457
- color: var(--odx-color-foreground-subtle);
458
- }
459
-
460
- .odx-text-disabled {
461
- color: var(--odx-color-foreground-disabled-rest);
337
+ .odx-text-strong {
338
+ font-weight: var(--odx-typography-font-weight-medium);
462
339
  }
463
340
 
464
- [class*="odx-title"], .odx-root :is(h1, h2, h3, h4, h5, h6) {
341
+ [class*="odx-title"], .odx-root :where(h1, h2, h3, h4, h5, h6) {
465
342
  text-wrap: balance;
466
- overflow-wrap: break-word;
343
+ font-family: var(--odx-typography-font-family-base);
467
344
  font-weight: var(--odx-typography-font-weight-semibold);
468
- display: block;
469
345
  }
470
346
 
471
347
  .odx-title {
@@ -528,78 +404,99 @@
528
404
  font-size: var(--odx-typography-font-size-display-xl);
529
405
  }
530
406
 
531
- :root {
532
- interpolate-size: allow-keywords;
407
+ .odx-no-overflow {
408
+ text-overflow: ellipsis;
409
+ white-space: nowrap;
410
+ overflow: hidden;
533
411
  }
534
412
 
535
- .odx-root {
536
- tab-size: 4;
537
- line-height: var(--odx-typography-line-height-base);
413
+ :where() {
414
+ background-color: var(--odx-color-background-selection);
538
415
  color: var(--odx-color-foreground-rest);
539
- font-family: var(--odx-typography-font-family-base), "Noto Sans", Kanit, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji";
540
- font-size: var(--odx-typography-font-size-base);
541
- text-size-adjust: 100%;
542
- -webkit-tap-highlight-color: transparent;
543
- scrollbar-width: thin;
416
+ }
544
417
 
545
- & ::selection {
546
- background-color: var(--odx-color-background-selection);
547
- color: var(--odx-color-foreground-rest);
548
- }
418
+ .odx-fg-rest {
419
+ color: var(--odx-color-foreground-rest);
549
420
  }
550
421
 
551
- html.odx-root {
552
- scroll-behavior: smooth;
553
- scrollbar-color: var(--odx-color-special-scrollbar) transparent;
554
- height: 100%;
422
+ .odx-fg-body {
423
+ color: var(--odx-color-foreground-on);
424
+ }
425
+
426
+ .odx-fg-inverse {
427
+ color: var(--odx-color-foreground-inverse-rest);
428
+ }
429
+
430
+ .odx-fg-inverse-static {
431
+ color: var(--odx-color-foreground-inverse-static);
432
+ }
433
+
434
+ .odx-fg-accent {
435
+ color: var(--odx-color-foreground-accent-rest);
436
+ }
437
+
438
+ .odx-fg-success {
439
+ color: var(--odx-color-foreground-success-rest);
440
+ }
441
+
442
+ .odx-fg-danger {
443
+ color: var(--odx-color-foreground-danger-rest);
444
+ }
445
+
446
+ .odx-fg-subtle {
447
+ color: var(--odx-color-foreground-subtle);
448
+ }
555
449
 
556
- &:not(:has(body.odx-light-mode), :has(body.odx-dark-mode)) {
557
- background-color: var(--odx-color-background-base);
558
- }
450
+ .odx-fg-disabled {
451
+ color: var(--odx-color-foreground-disabled-rest);
452
+ }
559
453
 
560
- & body {
561
- margin: 0;
562
- padding: 0;
563
- }
454
+ :is(.odx-bg-base, .odx-bg-content, .odx-bg-elevated):not(.odx-fg-disabled) {
455
+ color: var(--odx-color-foreground-rest);
564
456
  }
565
- }
566
457
 
567
- @layer odx.overrides {
568
- .odx-no-overflow {
569
- text-overflow: ellipsis;
570
- white-space: nowrap;
571
- overflow: hidden;
458
+ .odx-bg-base {
459
+ background-color: var(--odx-color-background-base);
572
460
  }
573
461
 
574
- .odx-visually-hidden:not(:focus-within), .odx-visually-hidden-force {
575
- clip-path: rect(0 0 0 0) !important;
576
- white-space: nowrap !important;
577
- border: none !important;
578
- width: 1px !important;
579
- height: 1px !important;
580
- padding: 0 !important;
581
- position: absolute !important;
582
- overflow: hidden !important;
462
+ .odx-bg-content {
463
+ background-color: var(--odx-color-background-level-1);
583
464
  }
584
465
 
585
- .odx-w-xs {
586
- max-width: var(--odx-layout-width-xs);
466
+ .odx-bg-elevated {
467
+ background-color: var(--odx-color-background-level-2);
587
468
  }
588
469
 
589
- .odx-w-sm {
590
- max-width: var(--odx-layout-width-sm);
470
+ .odx-bg-topmost {
471
+ background-color: var(--odx-color-background-level-3);
472
+
473
+ &:not(.odx-fg-disabled) {
474
+ color: var(--odx-color-foreground-inverse);
475
+ }
591
476
  }
592
477
 
593
- .odx-w-md {
594
- max-width: var(--odx-layout-width-md);
478
+ .odx-bg-brand {
479
+ background-color: var(--odx-color-background-brand);
480
+ color: var(--odx-color-foreground-inverse-static);
481
+
482
+ &.odx-fg-disabled, & .odx-fg-disabled {
483
+ color: var(--odx-color-foreground-disabled-on-brand);
484
+ }
595
485
  }
596
486
 
597
- .odx-w-lg {
598
- max-width: var(--odx-layout-width-lg);
487
+ .odx-bg-accent {
488
+ background-color: var(--odx-color-background-accent-rest);
489
+ color: var(--odx-color-foreground-inverse-static);
599
490
  }
600
491
 
601
- .odx-w-xl {
602
- max-width: var(--odx-layout-width-xl);
492
+ .odx-bg-danger {
493
+ background-color: var(--odx-color-background-danger-rest);
494
+ color: var(--odx-color-foreground-inverse-static);
495
+ }
496
+
497
+ .odx-bg-primary {
498
+ background-color: var(--odx-color-background-primary-rest);
499
+ color: var(--odx-color-foreground-inverse);
603
500
  }
604
501
 
605
502
  .odx-g-0 {
@@ -905,4 +802,272 @@
905
802
  .odx-mb-lg {
906
803
  margin-block-end: var(--odx-spacing-layout-lg);
907
804
  }
805
+
806
+ [class*="odx-w-xs"] {
807
+ max-width: var(--odx-layout-width-xs);
808
+ }
809
+
810
+ .odx-w-xs-static {
811
+ width: var(--odx-layout-width-xs);
812
+ }
813
+
814
+ [class*="odx-w-sm"] {
815
+ max-width: var(--odx-layout-width-sm);
816
+ }
817
+
818
+ .odx-w-sm-static {
819
+ width: var(--odx-layout-width-sm);
820
+ }
821
+
822
+ [class*="odx-w-md"] {
823
+ max-width: var(--odx-layout-width-md);
824
+ }
825
+
826
+ .odx-w-md-static {
827
+ width: var(--odx-layout-width-md);
828
+ }
829
+
830
+ [class*="odx-w-lg"] {
831
+ max-width: var(--odx-layout-width-lg);
832
+ }
833
+
834
+ .odx-w-lg-static {
835
+ width: var(--odx-layout-width-lg);
836
+ }
837
+
838
+ [class*="odx-w-xl"] {
839
+ max-width: var(--odx-layout-width-xl);
840
+ }
841
+
842
+ .odx-w-xl-static {
843
+ width: var(--odx-layout-width-xl);
844
+ }
845
+
846
+ [class*="odx-w-full"] {
847
+ max-width: 100%;
848
+ }
849
+
850
+ .odx-w-full-static {
851
+ width: 100%;
852
+ }
853
+
854
+ .odx-content :where(table), .odx-table {
855
+ --cell-size: var(--odx-size-300);
856
+ border-collapse: collapse;
857
+ background-color: #0000;
858
+ width: 100%;
859
+ max-width: 100%;
860
+
861
+ & caption {
862
+ line-height: var(--odx-typography-line-height-text-sm);
863
+ font-size: var(--odx-typography-font-size-text-sm);
864
+ font-weight: var(--odx-typography-font-weight-semibold);
865
+ }
866
+
867
+ & thead {
868
+ background-color: inherit;
869
+ }
870
+
871
+ & tr {
872
+ transition: var(--odx-motion-transition-reduced);
873
+ background-color: var(--odx-color-background-transparent);
874
+ transition-property: background-color, color;
875
+ }
876
+
877
+ & tr:has(td):hover {
878
+ background-color: var(--odx-color-background-transparent-hover);
879
+ }
880
+
881
+ & th, & td {
882
+ padding: var(--odx-control-spacing-md) var(--odx-control-spacing-inline-md);
883
+ min-height: var(--odx-size-250);
884
+ text-align: start;
885
+ font-size: inherit;
886
+ }
887
+
888
+ & th {
889
+ border-bottom: var(--odx-border-width-thin) solid var(--odx-color-stroke-neutral-subtle);
890
+ vertical-align: top;
891
+ font-weight: var(--odx-typography-font-weight-medium);
892
+ cursor: default;
893
+ user-select: none;
894
+ }
895
+
896
+ & td {
897
+ height: var(--cell-size);
898
+ vertical-align: middle;
899
+ }
900
+
901
+ & tr:not(:last-child) td {
902
+ border-bottom: var(--odx-border-width-thin) solid var(--odx-color-stroke-neutral-subtle);
903
+ }
904
+
905
+ & th :is(odx-input, odx-select) {
906
+ margin-inline: var(--odx-spacing-negative-50);
907
+ }
908
+ }
909
+
910
+ .odx-content {
911
+ --_content-spacing-sm: var(--odx-spacing-layout-sm);
912
+ --_content-spacing-md: var(--odx-spacing-layout-md);
913
+ --_content-spacing-lg: var(--odx-spacing-layout-lg);
914
+ line-height: var(--odx-typography-line-height-text-md);
915
+
916
+ & table, & ul, & ol, & dl, & blockquote, & pre, & figure, & video, & embed, & iframe {
917
+ margin: var(--_content-spacing-md) 0;
918
+ }
919
+
920
+ & :is(odx-key-value-list, odx-list) {
921
+ margin-block: var(--_content-spacing-md);
922
+
923
+ & :is(odx-key-value-list, odx-list) {
924
+ margin-block: 0;
925
+ }
926
+ }
927
+
928
+ & > :is(odx-text, .odx-text), & li > :is(ul, ol, dl), & p, & li {
929
+ margin: var(--_content-spacing-sm) 0;
930
+ }
931
+
932
+ & :is(odx-text, .odx-text), & p {
933
+ &:first-child {
934
+ margin-block-start: 0;
935
+ }
936
+ }
937
+
938
+ & > :is(odx-title, [class*="odx-title"]), & h1, & h2, & h3, & h4, & h5, & h6 {
939
+ margin-block: var(--_content-spacing-lg) var(--_content-spacing-sm);
940
+
941
+ &:first-child {
942
+ margin-block-start: var(--_content-spacing-sm);
943
+ }
944
+ }
945
+
946
+ & table, & ul, & ol, & dl, & blockquote {
947
+ padding-inline-start: var(--odx-spacing-150);
948
+ }
949
+
950
+ & code, & pre, & mark {
951
+ border-radius: var(--odx-border-radius-sm);
952
+ padding: 0 var(--odx-spacing-12);
953
+ }
954
+
955
+ & code, & pre {
956
+ background-color: var(--odx-color-background-control-rest);
957
+ font-size: var(--odx-typography-font-size-text-sm);
958
+ }
959
+
960
+ & blockquote {
961
+ padding-inline-end: var(--odx-spacing-150);
962
+ }
963
+
964
+ & dt {
965
+ font-weight: var(--odx-typography-font-weight-medium);
966
+ }
967
+
968
+ & a {
969
+ text-decoration: underline;
970
+ }
971
+
972
+ & del {
973
+ color: var(--odx-color-foreground-danger-rest);
974
+ }
975
+
976
+ & figure {
977
+ flex-direction: column;
978
+ display: flex;
979
+ }
980
+
981
+ & figcaption {
982
+ padding: var(--_content-spacing-sm);
983
+ line-height: var(--odx-typography-line-height-text-sm);
984
+ font-size: var(--odx-typography-font-size-text-sm);
985
+ }
986
+
987
+ & ins {
988
+ color: var(--odx-color-foreground-success-rest);
989
+ text-decoration: none;
990
+ }
991
+
992
+ & mark {
993
+ background-color: var(--odx-color-background-selection);
994
+ color: var(--odx-color-foreground-rest);
995
+ }
996
+
997
+ & pre {
998
+ padding: var(--odx-control-spacing-md) calc(2 * var(--odx-control-spacing-inline-md));
999
+ }
1000
+
1001
+ & small {
1002
+ font-size: var(--odx-typography-font-size-text-sm);
1003
+ }
1004
+
1005
+ & var {
1006
+ font-weight: var(--odx-typography-font-weight-medium);
1007
+ }
1008
+ }
1009
+
1010
+ .odx-content-sm {
1011
+ --_content-spacing-md: var(--odx-spacing-layout-sm);
1012
+ --_content-spacing-lg: var(--odx-spacing-layout-md);
1013
+ line-height: var(--odx-typography-line-height-text-sm);
1014
+ font-size: var(--odx-typography-font-size-text-sm);
1015
+ }
1016
+
1017
+ .odx-content-box {
1018
+ background-color: var(--odx-color-background-level-1);
1019
+ padding: var(--odx-spacing-layout-lg);
1020
+ border-radius: 0;
1021
+ }
1022
+ }
1023
+
1024
+ @layer odx-overrides;
1025
+
1026
+ .odx-slot-placeholder-sm, .odx-slot-placeholder {
1027
+ background-color: var(--odx-color-background-accent-subtle);
1028
+ padding: var(--odx-spacing-layout-sm) var(--odx-spacing-layout-lg);
1029
+ height: 100%;
1030
+ min-height: var(--odx-control-height-md);
1031
+ text-align: center;
1032
+ text-overflow: ellipsis;
1033
+ pointer-events: none;
1034
+ user-select: none;
1035
+ flex: 1;
1036
+ place-content: center;
1037
+ overflow: hidden;
1038
+
1039
+ &:before, &:after {
1040
+ display: block;
1041
+ }
1042
+
1043
+ &:before {
1044
+ text-transform: capitalize;
1045
+ font-size: var(--odx-typography-font-size-text-sm);
1046
+ font-weight: var(--odx-typography-font-weight-medium);
1047
+ content: attr(slot, "default") " slot";
1048
+ }
1049
+
1050
+ &:after {
1051
+ line-height: var(--odx-typography-line-height-text-xs);
1052
+ color: var(--odx-color-foreground-subtle);
1053
+ font-size: var(--odx-typography-font-size-text-xs);
1054
+ content: "This is a placeholder. A Replace with your own content";
1055
+ }
1056
+ }
1057
+
1058
+ .odx-slot-placeholder-sm {
1059
+ padding: var(--odx-spacing-12) var(--odx-spacing-layout-sm);
1060
+ min-height: var(--odx-control-addon-size-md);
1061
+ font-size: var(--odx-typography-font-size-text-sm);
1062
+
1063
+ &:after {
1064
+ display: none;
1065
+ }
1066
+ }
1067
+
1068
+ :root {
1069
+ --odx-layout-width-page-min: 340px;
1070
+ --odx-layout-width-page-default: 1440px;
1071
+ --odx-layout-width-page-narrow: 1200px;
1072
+ --odx-layout-width-page-wide: 1800px;
908
1073
  }
package/package.json CHANGED
@@ -2,14 +2,14 @@
2
2
  "name": "@odx/foundation",
3
3
  "displayName": "ODX Design System Foundation",
4
4
  "description": "The design foundation of the ODX Design System, providing base styles and utilities",
5
- "version": "1.0.0-rc.4",
5
+ "version": "1.0.0-rc.6",
6
6
  "author": "Drägerwerk AG & Co.KGaA",
7
7
  "license": "SEE LICENSE IN LICENSE",
8
8
  "homepage": "https://odx.draeger.com",
9
9
  "files": [
10
10
  "dist",
11
+ "types",
11
12
  "CHANGELOG.md",
12
- "LICENSE",
13
13
  "!dist/**/*.map"
14
14
  ],
15
15
  "type": "module",
@@ -21,8 +21,8 @@
21
21
  },
22
22
  "devDependencies": {
23
23
  "@tsdown/css": "0.22.0",
24
- "lit": "3.3.2",
25
- "stylelint": "17.11.0",
24
+ "lit": "3.3.3",
25
+ "stylelint": "17.11.1",
26
26
  "tsdown": "0.22.0",
27
27
  "@odx-internal/config-stylelint": "0.0.0",
28
28
  "@odx-internal/utils-storybook": "0.0.0"
@@ -39,7 +39,10 @@
39
39
  "import": "./dist/main.js",
40
40
  "types": "./dist/main.d.ts"
41
41
  },
42
- "./styles": "./dist/styles.css"
42
+ "./styles": {
43
+ "import": "./dist/styles.css",
44
+ "types": "./types/styles.d.ts"
45
+ }
43
46
  },
44
47
  "publishConfig": {
45
48
  "access": "public",
@@ -0,0 +1,3 @@
1
+ declare const content: string;
2
+
3
+ export default content;