@moodlehq/design-system 4.0.0 → 5.0.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 (81) hide show
  1. package/README.md +16 -6
  2. package/dist/components/_index.legacy.scss +1893 -0
  3. package/dist/components/activity-icon/ActivityIcon.d.ts +3 -3
  4. package/dist/components/activity-icon/ActivityIcon.js +5 -5
  5. package/dist/components/activity-icon/ActivityIcon.js.map +1 -1
  6. package/dist/components/activity-icon/index.css +99 -0
  7. package/dist/components/badge/Badge.d.ts +1 -1
  8. package/dist/components/badge/{Badge2.js → Badge.js} +1 -2
  9. package/dist/components/badge/Badge.js.map +1 -0
  10. package/dist/components/badge/index.css +115 -0
  11. package/dist/components/badge/index.js +1 -1
  12. package/dist/components/button/index.css +295 -0
  13. package/dist/components/checkbox/index.css +181 -0
  14. package/dist/components/choicebox/Choicebox.d.ts +21 -0
  15. package/dist/components/choicebox/Choicebox.js +55 -0
  16. package/dist/components/choicebox/Choicebox.js.map +1 -0
  17. package/dist/components/choicebox/index.css +364 -0
  18. package/dist/components/choicebox/index.d.ts +1 -0
  19. package/dist/components/choicebox/index.js +2 -0
  20. package/dist/components/close-button/CloseButton.d.ts +1 -1
  21. package/dist/components/close-button/index.css +47 -0
  22. package/dist/components/favourite-button/FavouriteButton.d.ts +15 -0
  23. package/dist/components/favourite-button/FavouriteButton.js +25 -0
  24. package/dist/components/favourite-button/FavouriteButton.js.map +1 -0
  25. package/dist/components/favourite-button/index.css +86 -0
  26. package/dist/components/favourite-button/index.d.ts +2 -0
  27. package/dist/components/favourite-button/index.js +2 -0
  28. package/dist/components/index.css +12 -0
  29. package/dist/components/index.d.ts +12 -0
  30. package/dist/components/link/Link.d.ts +11 -0
  31. package/dist/components/link/Link.js +65 -0
  32. package/dist/components/link/Link.js.map +1 -0
  33. package/dist/components/link/index.css +122 -0
  34. package/dist/components/link/index.d.ts +1 -0
  35. package/dist/components/link/index.js +2 -0
  36. package/dist/components/nav-pill/NavPill.d.ts +21 -0
  37. package/dist/components/nav-pill/NavPill.js +54 -0
  38. package/dist/components/nav-pill/NavPill.js.map +1 -0
  39. package/dist/components/nav-pill/index.css +96 -0
  40. package/dist/components/nav-pill/index.d.ts +1 -0
  41. package/dist/components/nav-pill/index.js +2 -0
  42. package/dist/components/pagination/Pagination.d.ts +32 -0
  43. package/dist/components/pagination/Pagination.js +100 -0
  44. package/dist/components/pagination/Pagination.js.map +1 -0
  45. package/dist/components/pagination/index.css +139 -0
  46. package/dist/components/pagination/index.d.ts +1 -0
  47. package/dist/components/pagination/index.js +2 -0
  48. package/dist/components/pagination/pagination.helpers.d.ts +26 -0
  49. package/dist/components/pagination/pagination.helpers.js +136 -0
  50. package/dist/components/pagination/pagination.helpers.js.map +1 -0
  51. package/dist/components/progress-bar/ProgressBar.d.ts +35 -0
  52. package/dist/components/progress-bar/ProgressBar.js +86 -0
  53. package/dist/components/progress-bar/ProgressBar.js.map +1 -0
  54. package/dist/components/progress-bar/index.css +193 -0
  55. package/dist/components/progress-bar/index.d.ts +1 -0
  56. package/dist/components/progress-bar/index.js +2 -0
  57. package/dist/components/radio/index.css +133 -0
  58. package/dist/index.css +1101 -150
  59. package/dist/index.js +8 -2
  60. package/{tokens → dist/tokens}/css/colors.css +7 -4
  61. package/{tokens → dist/tokens}/css/primitives.css +1 -1
  62. package/{tokens → dist/tokens}/scss/_colors.scss +8 -5
  63. package/{tokens → dist/tokens}/scss/_index_css_vars.scss +3 -0
  64. package/{tokens → dist/tokens}/scss/_primitives.scss +1 -1
  65. package/{tokens → dist/tokens}/scss/_typography.scss +1 -1
  66. package/package.json +16 -7
  67. package/dist/components/badge/Badge2.js.map +0 -1
  68. /package/{tokens → dist/tokens}/css/borders.css +0 -0
  69. /package/{tokens → dist/tokens}/css/breakpoints.css +0 -0
  70. /package/{tokens → dist/tokens}/css/index.css +0 -0
  71. /package/{tokens → dist/tokens}/css/shadows.css +0 -0
  72. /package/{tokens → dist/tokens}/css/sizes.css +0 -0
  73. /package/{tokens → dist/tokens}/css/spacing.css +0 -0
  74. /package/{tokens → dist/tokens}/css/typography.css +0 -0
  75. /package/{tokens → dist/tokens}/scss/_borders.scss +0 -0
  76. /package/{tokens → dist/tokens}/scss/_breakpoints.scss +0 -0
  77. /package/{tokens → dist/tokens}/scss/_index.legacy.scss +0 -0
  78. /package/{tokens → dist/tokens}/scss/_index.scss +0 -0
  79. /package/{tokens → dist/tokens}/scss/_shadows.scss +0 -0
  80. /package/{tokens → dist/tokens}/scss/_sizes.scss +0 -0
  81. /package/{tokens → dist/tokens}/scss/_spacing.scss +0 -0
@@ -1,6 +1,6 @@
1
1
  import { HTMLAttributes } from 'react';
2
2
  import { ActivityIconName } from './activityIconRegistry';
3
- export type ActivityIconVariant = 'none' | 'default' | 'large';
3
+ export type ActivityIconContainer = 'none' | 'default' | 'large';
4
4
  export type ActivityIconSize = 'sm' | 'md' | 'lg' | 'xl';
5
5
  export interface ActivityIconProps extends HTMLAttributes<HTMLSpanElement> {
6
6
  /**
@@ -14,10 +14,10 @@ export interface ActivityIconProps extends HTMLAttributes<HTMLSpanElement> {
14
14
  /**
15
15
  * Visual container style around the icon.
16
16
  */
17
- variant?: ActivityIconVariant;
17
+ container?: ActivityIconContainer;
18
18
  /**
19
19
  * Icon size token.
20
20
  */
21
21
  size?: ActivityIconSize;
22
22
  }
23
- export declare const ActivityIcon: ({ icon, alt, variant, size, className, ...props }: ActivityIconProps) => import("react/jsx-runtime").JSX.Element;
23
+ export declare const ActivityIcon: ({ icon, alt, container, size, className, ...props }: ActivityIconProps) => import("react").JSX.Element;
@@ -2,7 +2,7 @@ import { activityIconNames, activityIconRegistry } from "./activityIconRegistry.
2
2
  import { useEffect, useState } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  //#region components/activity-icon/ActivityIcon.tsx
5
- var iconGlob = /* @__PURE__ */ Object.assign({
5
+ var iconGlob = /* #__PURE__ */ Object.assign({
6
6
  "./assets/assignment.svg": () => import("./assets/assignment.js"),
7
7
  "./assets/bigbluebutton.svg": () => import("./assets/bigbluebutton.js"),
8
8
  "./assets/book.svg": () => import("./assets/book.js"),
@@ -65,7 +65,7 @@ function loadIconSrc(fileName) {
65
65
  if (!loader) return Promise.reject(/* @__PURE__ */ new Error(`[MDS ActivityIcon] Icon file "${fileName}.svg" not found in assets.`));
66
66
  return loader().then((mod) => mod.default);
67
67
  }
68
- var allowedVariants = [
68
+ var allowedContainers = [
69
69
  "none",
70
70
  "default",
71
71
  "large"
@@ -77,7 +77,7 @@ var allowedSizes = [
77
77
  "xl"
78
78
  ];
79
79
  var iconLookupFallback = "file-unknown";
80
- var ActivityIcon = ({ icon, alt = "", variant, size, className, ...props }) => {
80
+ var ActivityIcon = ({ icon, alt = "", container, size, className, ...props }) => {
81
81
  const normalizedIcon = icon?.toLowerCase();
82
82
  const hasValidIcon = normalizedIcon !== void 0 && normalizedIcon in activityIconRegistry;
83
83
  if (!hasValidIcon) {
@@ -85,7 +85,7 @@ var ActivityIcon = ({ icon, alt = "", variant, size, className, ...props }) => {
85
85
  console.error(`${invalidIconMessage}. Falling back to "${iconLookupFallback}" placeholder.`);
86
86
  }
87
87
  const resolvedIcon = hasValidIcon ? normalizedIcon : iconLookupFallback;
88
- const resolvedVariant = variant && allowedVariants.includes(variant) ? variant : "default";
88
+ const resolvedContainer = container && allowedContainers.includes(container) ? container : "default";
89
89
  const resolvedSize = size && allowedSizes.includes(size) ? size : "md";
90
90
  const resolvedCategory = activityIconRegistry[resolvedIcon].category;
91
91
  const [iconSrc, setIconSrc] = useState(void 0);
@@ -103,7 +103,7 @@ var ActivityIcon = ({ icon, alt = "", variant, size, className, ...props }) => {
103
103
  }, [resolvedIcon]);
104
104
  const classes = [
105
105
  "mds-activity-icon",
106
- `mds-activity-icon--${resolvedVariant}`,
106
+ `mds-activity-icon--${resolvedContainer}`,
107
107
  `mds-activity-icon--size-${resolvedSize}`,
108
108
  `mds-activity-icon--category-${resolvedCategory}`
109
109
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"ActivityIcon.js","names":[],"sources":["../../../components/activity-icon/ActivityIcon.tsx"],"sourcesContent":["import type { HTMLAttributes } from 'react';\nimport { useEffect, useState } from 'react';\nimport type { ActivityIconName } from './activityIconRegistry';\nimport {\n activityIconNames,\n activityIconRegistry,\n} from './activityIconRegistry';\n\nconst iconGlob = import.meta.glob<{ default: string }>('./assets/*.svg', {\n eager: false,\n});\n\nfunction loadIconSrc(fileName: string): Promise<string> {\n const globPath = `./assets/${fileName}.svg`;\n const loader = iconGlob[globPath];\n\n if (!loader) {\n return Promise.reject(\n new Error(\n `[MDS ActivityIcon] Icon file \"${fileName}.svg\" not found in assets.`,\n ),\n );\n }\n\n return loader().then((mod) => mod.default);\n}\n\nexport type ActivityIconVariant = 'none' | 'default' | 'large';\nconst allowedVariants: ActivityIconVariant[] = ['none', 'default', 'large'];\n\nexport type ActivityIconSize = 'sm' | 'md' | 'lg' | 'xl';\nconst allowedSizes: ActivityIconSize[] = ['sm', 'md', 'lg', 'xl'];\nconst iconLookupFallback: ActivityIconName = 'file-unknown';\n\nexport interface ActivityIconProps extends HTMLAttributes<HTMLSpanElement> {\n /**\n * Activity/resource icon key used to resolve the SVG asset from the registry.\n */\n icon: ActivityIconName;\n /**\n * Accessible text for the rendered image. Use an empty string for decorative icons.\n */\n alt?: string;\n /**\n * Visual container style around the icon.\n */\n variant?: ActivityIconVariant;\n /**\n * Icon size token.\n */\n size?: ActivityIconSize;\n}\n\nexport const ActivityIcon = ({\n icon,\n alt = '',\n variant,\n size,\n className,\n ...props\n}: ActivityIconProps) => {\n // TS callers must pass icon, but JS consumers can still provide undefined at runtime.\n const normalizedIcon = icon?.toLowerCase();\n const hasValidIcon =\n normalizedIcon !== undefined && normalizedIcon in activityIconRegistry;\n\n if (!hasValidIcon) {\n const invalidIconMessage = `[MDS ActivityIcon] Invalid icon \"${icon}\". Allowed: ${activityIconNames.join(', ')}`;\n console.error(\n `${invalidIconMessage}. Falling back to \"${iconLookupFallback}\" placeholder.`,\n );\n }\n\n if (import.meta.env.DEV && variant && !allowedVariants.includes(variant)) {\n console.warn(\n `[MDS ActivityIcon] Invalid variant \"${variant}\". Falling back to \"default\". Allowed: ${allowedVariants.join(', ')}`,\n );\n }\n\n if (import.meta.env.DEV && size && !allowedSizes.includes(size)) {\n console.warn(\n `[MDS ActivityIcon] Invalid size \"${size}\". Falling back to \"md\". Allowed: ${allowedSizes.join(', ')}`,\n );\n }\n\n const resolvedIcon: ActivityIconName = hasValidIcon\n ? (normalizedIcon as ActivityIconName)\n : iconLookupFallback;\n const resolvedVariant =\n variant && allowedVariants.includes(variant) ? variant : 'default';\n const resolvedSize = size && allowedSizes.includes(size) ? size : 'md';\n const resolvedCategory = activityIconRegistry[resolvedIcon].category;\n const [iconSrc, setIconSrc] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n let isMounted = true;\n const { fileName } = activityIconRegistry[resolvedIcon];\n\n void loadIconSrc(fileName)\n .then((src) => {\n if (isMounted) {\n setIconSrc(src);\n }\n })\n .catch(() => {\n if (isMounted) {\n setIconSrc(undefined);\n }\n });\n\n return () => {\n isMounted = false;\n };\n }, [resolvedIcon]);\n\n const classes = [\n 'mds-activity-icon',\n `mds-activity-icon--${resolvedVariant}`,\n `mds-activity-icon--size-${resolvedSize}`,\n `mds-activity-icon--category-${resolvedCategory}`,\n ];\n if (className) {\n classes.push(className);\n }\n\n return (\n <span className={classes.join(' ')} {...props}>\n <img alt={alt} className=\"mds-activity-icon__asset\" src={iconSrc} />\n </span>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ActivityIcon.js","names":[],"sources":["../../../components/activity-icon/ActivityIcon.tsx"],"sourcesContent":["import type { HTMLAttributes } from 'react';\nimport { useEffect, useState } from 'react';\nimport type { ActivityIconName } from './activityIconRegistry';\nimport {\n activityIconNames,\n activityIconRegistry,\n} from './activityIconRegistry';\n\nconst iconGlob = import.meta.glob<{ default: string }>('./assets/*.svg', {\n eager: false,\n});\n\nfunction loadIconSrc(fileName: string): Promise<string> {\n const globPath = `./assets/${fileName}.svg`;\n const loader = iconGlob[globPath];\n\n if (!loader) {\n return Promise.reject(\n new Error(\n `[MDS ActivityIcon] Icon file \"${fileName}.svg\" not found in assets.`,\n ),\n );\n }\n\n return loader().then((mod) => mod.default);\n}\n\nexport type ActivityIconContainer = 'none' | 'default' | 'large';\nconst allowedContainers: ActivityIconContainer[] = ['none', 'default', 'large'];\n\nexport type ActivityIconSize = 'sm' | 'md' | 'lg' | 'xl';\nconst allowedSizes: ActivityIconSize[] = ['sm', 'md', 'lg', 'xl'];\nconst iconLookupFallback: ActivityIconName = 'file-unknown';\n\nexport interface ActivityIconProps extends HTMLAttributes<HTMLSpanElement> {\n /**\n * Activity/resource icon key used to resolve the SVG asset from the registry.\n */\n icon: ActivityIconName;\n /**\n * Accessible text for the rendered image. Use an empty string for decorative icons.\n */\n alt?: string;\n /**\n * Visual container style around the icon.\n */\n container?: ActivityIconContainer;\n /**\n * Icon size token.\n */\n size?: ActivityIconSize;\n}\n\nexport const ActivityIcon = ({\n icon,\n alt = '',\n container,\n size,\n className,\n ...props\n}: ActivityIconProps) => {\n // TS callers must pass icon, but JS consumers can still provide undefined at runtime.\n const normalizedIcon = icon?.toLowerCase();\n const hasValidIcon =\n normalizedIcon !== undefined && normalizedIcon in activityIconRegistry;\n\n if (!hasValidIcon) {\n const invalidIconMessage = `[MDS ActivityIcon] Invalid icon \"${icon}\". Allowed: ${activityIconNames.join(', ')}`;\n console.error(\n `${invalidIconMessage}. Falling back to \"${iconLookupFallback}\" placeholder.`,\n );\n }\n\n if (\n import.meta.env.DEV &&\n container &&\n !allowedContainers.includes(container)\n ) {\n console.warn(\n `[MDS ActivityIcon] Invalid container \"${container}\". Falling back to \"default\". Allowed: ${allowedContainers.join(', ')}`,\n );\n }\n\n if (import.meta.env.DEV && size && !allowedSizes.includes(size)) {\n console.warn(\n `[MDS ActivityIcon] Invalid size \"${size}\". Falling back to \"md\". Allowed: ${allowedSizes.join(', ')}`,\n );\n }\n\n const resolvedIcon: ActivityIconName = hasValidIcon\n ? (normalizedIcon as ActivityIconName)\n : iconLookupFallback;\n const resolvedContainer =\n container && allowedContainers.includes(container) ? container : 'default';\n const resolvedSize = size && allowedSizes.includes(size) ? size : 'md';\n const resolvedCategory = activityIconRegistry[resolvedIcon].category;\n const [iconSrc, setIconSrc] = useState<string | undefined>(undefined);\n\n useEffect(() => {\n let isMounted = true;\n const { fileName } = activityIconRegistry[resolvedIcon];\n\n void loadIconSrc(fileName)\n .then((src) => {\n if (isMounted) {\n setIconSrc(src);\n }\n })\n .catch(() => {\n if (isMounted) {\n setIconSrc(undefined);\n }\n });\n\n return () => {\n isMounted = false;\n };\n }, [resolvedIcon]);\n\n const classes = [\n 'mds-activity-icon',\n `mds-activity-icon--${resolvedContainer}`,\n `mds-activity-icon--size-${resolvedSize}`,\n `mds-activity-icon--category-${resolvedCategory}`,\n ];\n if (className) {\n classes.push(className);\n }\n\n return (\n <span className={classes.join(' ')} {...props}>\n <img alt={alt} className=\"mds-activity-icon__asset\" src={iconSrc} />\n </span>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ .mds-activity-icon {
2
+ align-items: center;
3
+ /*
4
+ * content-box so block-size/inline-size declare the ICON content area.
5
+ * Padding then expands the tile beyond that — matching Figma's structure
6
+ * where "size" is the icon and padding is added by the container variant.
7
+ */
8
+ box-sizing: content-box;
9
+ display: inline-flex;
10
+ flex-shrink: 0;
11
+ justify-content: center;
12
+ overflow: hidden;
13
+ }
14
+
15
+ /* none: no background tile, no padding — tile equals the icon size */
16
+ .mds-activity-icon--none {
17
+ border-radius: var(--mds-border-radius-none);
18
+ }
19
+
20
+ /*
21
+ * default: 8px padding each side — tile = icon + 16px (e.g. lg: 24+16 = 40px total).
22
+ * large: 12px padding each side — tile = icon + 24px (e.g. lg: 24+24 = 48px total).
23
+ */
24
+ .mds-activity-icon--default {
25
+ border-radius: var(--mds-border-radius-xl);
26
+ padding: var(--mds-spacing-xs);
27
+ }
28
+
29
+ .mds-activity-icon--large {
30
+ border-radius: var(--mds-border-radius-xl);
31
+ padding: var(--mds-spacing-sm);
32
+ }
33
+
34
+ /* Figma uses a smaller outer radius for default+sm only. */
35
+ .mds-activity-icon--default.mds-activity-icon--size-sm {
36
+ border-radius: var(--mds-border-radius-lg);
37
+ }
38
+
39
+ /* Category background colors apply only when a background container is active. */
40
+ .mds-activity-icon--default.mds-activity-icon--category-assessment,
41
+ .mds-activity-icon--large.mds-activity-icon--category-assessment {
42
+ background-color: var(--mds-activity-icon-assessment-bg);
43
+ }
44
+
45
+ .mds-activity-icon--default.mds-activity-icon--category-collaboration,
46
+ .mds-activity-icon--large.mds-activity-icon--category-collaboration {
47
+ background-color: var(--mds-activity-icon-collaboration-bg);
48
+ }
49
+
50
+ .mds-activity-icon--default.mds-activity-icon--category-communication,
51
+ .mds-activity-icon--large.mds-activity-icon--category-communication {
52
+ background-color: var(--mds-activity-icon-communication-bg);
53
+ }
54
+
55
+ .mds-activity-icon--default.mds-activity-icon--category-interactive,
56
+ .mds-activity-icon--large.mds-activity-icon--category-interactive {
57
+ background-color: var(--mds-activity-icon-interactive-bg);
58
+ }
59
+
60
+ .mds-activity-icon--default.mds-activity-icon--category-other,
61
+ .mds-activity-icon--large.mds-activity-icon--category-other {
62
+ background-color: var(--mds-activity-icon-other-bg);
63
+ }
64
+
65
+ .mds-activity-icon--default.mds-activity-icon--category-resource,
66
+ .mds-activity-icon--large.mds-activity-icon--category-resource {
67
+ background-color: var(--mds-activity-icon-resource-bg);
68
+ }
69
+
70
+ /* Size variants */
71
+ .mds-activity-icon--size-sm {
72
+ block-size: var(--mds-icons-sm);
73
+ inline-size: var(--mds-icons-sm);
74
+ }
75
+
76
+ .mds-activity-icon--size-md {
77
+ /* Intentionally follows the Figma token mapping, where md uses the lg icon token. */
78
+ block-size: var(--mds-icons-lg);
79
+ inline-size: var(--mds-icons-lg);
80
+ }
81
+
82
+ .mds-activity-icon--size-lg {
83
+ /* Intentionally follows the Figma token mapping, where lg uses the xl icon token. */
84
+ block-size: var(--mds-icons-xl);
85
+ inline-size: var(--mds-icons-xl);
86
+ }
87
+
88
+ .mds-activity-icon--size-xl {
89
+ /* Intentionally follows the Figma token mapping, where xl uses the xxl icon token. */
90
+ block-size: var(--mds-icons-xxl);
91
+ inline-size: var(--mds-icons-xxl);
92
+ }
93
+
94
+ .mds-activity-icon__asset {
95
+ block-size: 100%;
96
+ border-radius: var(--mds-border-radius-xs);
97
+ display: block;
98
+ inline-size: 100%;
99
+ }
@@ -15,5 +15,5 @@ export interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
15
15
  /** Optional icon rendered after the label. Must be an `<i>` or `<svg>` element. Mutually exclusive with `startIcon`. */
16
16
  endIcon?: IconElement;
17
17
  }
18
- export declare const Badge: ({ label, variant, subtle, pill, startIcon, endIcon, className, ...props }: BadgeProps) => import("react/jsx-runtime").JSX.Element;
18
+ export declare const Badge: ({ label, variant, subtle, pill, startIcon, endIcon, className, ...props }: BadgeProps) => import("react").JSX.Element;
19
19
  export {};
@@ -1,4 +1,3 @@
1
- /* empty css */
2
1
  import { isValidElement } from "react";
3
2
  import { jsxs } from "react/jsx-runtime";
4
3
  //#region components/badge/Badge.tsx
@@ -40,4 +39,4 @@ var Badge = ({ label, variant, subtle = false, pill = false, startIcon, endIcon,
40
39
  //#endregion
41
40
  export { Badge };
42
41
 
43
- //# sourceMappingURL=Badge2.js.map
42
+ //# sourceMappingURL=Badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Badge.js","names":[],"sources":["../../../components/badge/Badge.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactElement } from 'react';\nimport { isValidElement } from 'react';\n\ntype BadgeVariant =\n | 'primary'\n | 'secondary'\n | 'success'\n | 'danger'\n | 'warning'\n | 'info';\n\ntype IconElement = ReactElement<'i' | 'svg'>;\n\n// Runtime guard — icon props must be <i> or <svg> elements\nconst isIconElement = (el: unknown, propName: string): el is IconElement => {\n const valid = isValidElement(el) && (el.type === 'i' || el.type === 'svg');\n if (!valid && el != null && import.meta.env.DEV) {\n console.error(`Badge: \\`${propName}\\` must be an <i> or <svg> element.`);\n }\n return valid;\n};\n\nconst allowedVariants: BadgeVariant[] = [\n 'primary',\n 'secondary',\n 'success',\n 'danger',\n 'warning',\n 'info',\n];\n\nexport interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {\n /** Visible badge text. Must be a caller-supplied translated string. */\n label: string;\n /** Colour/semantic variant. Defaults to `primary`. */\n variant?: BadgeVariant;\n /** When true, renders the low-contrast (subtle) style with a light background and border. */\n subtle?: boolean;\n /** When true, renders fully rounded pill shape instead of the default slight rounding. */\n pill?: boolean;\n /** Optional icon rendered before the label. Must be an `<i>` or `<svg>` element. Mutually exclusive with `endIcon`. */\n startIcon?: IconElement;\n /** Optional icon rendered after the label. Must be an `<i>` or `<svg>` element. Mutually exclusive with `startIcon`. */\n endIcon?: IconElement;\n}\n\nexport const Badge = ({\n label,\n variant,\n subtle = false,\n pill = false,\n startIcon,\n endIcon,\n className,\n ...props\n}: BadgeProps) => {\n const resolvedVariant =\n variant && allowedVariants.includes(variant as BadgeVariant)\n ? variant\n : 'primary';\n\n const resolvedStartIcon = isIconElement(startIcon, 'startIcon')\n ? startIcon\n : null;\n let resolvedEndIcon = isIconElement(endIcon, 'endIcon') ? endIcon : null;\n\n if (import.meta.env.DEV) {\n if (variant && !allowedVariants.includes(variant as BadgeVariant)) {\n console.warn(\n `[MDS Badge] Invalid variant \"${variant}\". Falling back to \"primary\". Allowed: ${allowedVariants.join(', ')}`,\n );\n }\n if (resolvedStartIcon && resolvedEndIcon) {\n console.warn(\n '[MDS Badge] `startIcon` and `endIcon` are mutually exclusive. Rendering `startIcon` only.',\n );\n }\n }\n\n // Only one icon can be rendered at a time; startIcon takes precedence when both are provided.\n if (resolvedStartIcon && resolvedEndIcon) {\n resolvedEndIcon = null;\n }\n\n const classes = ['mds-badge', 'badge', `mds-badge--${resolvedVariant}`];\n if (resolvedStartIcon || resolvedEndIcon) classes.push('mds-badge--has-icon');\n if (subtle) classes.push('mds-badge--subtle');\n if (pill) classes.push('mds-badge--pill');\n if (className) classes.push(className);\n\n return (\n <span className={classes.join(' ')} {...props}>\n {resolvedStartIcon}\n {label}\n {resolvedEndIcon}\n </span>\n );\n};\n"],"mappings":";;;AAcA,IAAM,iBAAiB,IAAa,aAAwC;CAK1E,OAJc,eAAe,EAAE,MAAM,GAAG,SAAS,OAAO,GAAG,SAAS;AAKtE;AAEA,IAAM,kBAAkC;CACtC;CACA;CACA;CACA;CACA;CACA;AACF;AAiBA,IAAa,SAAS,EACpB,OACA,SACA,SAAS,OACT,OAAO,OACP,WACA,SACA,WACA,GAAG,YACa;CAChB,MAAM,kBACJ,WAAW,gBAAgB,SAAS,OAAuB,IACvD,UACA;CAEN,MAAM,oBAAoB,cAAc,WAAW,WAAW,IAC1D,YACA;CACJ,IAAI,kBAAkB,cAAc,SAAS,SAAS,IAAI,UAAU;CAgBpE,IAAI,qBAAqB,iBACvB,kBAAkB;CAGpB,MAAM,UAAU;EAAC;EAAa;EAAS,cAAc;CAAiB;CACtE,IAAI,qBAAqB,iBAAiB,QAAQ,KAAK,qBAAqB;CAC5E,IAAI,QAAQ,QAAQ,KAAK,mBAAmB;CAC5C,IAAI,MAAM,QAAQ,KAAK,iBAAiB;CACxC,IAAI,WAAW,QAAQ,KAAK,SAAS;CAErC,OACE,qBAAC,QAAD;EAAM,WAAW,QAAQ,KAAK,GAAG;EAAG,GAAI;YAAxC;GACG;GACA;GACA;EACG;;AAEV"}
@@ -0,0 +1,115 @@
1
+ .mds-badge {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: 0;
5
+ padding: var(--mds-spacing-xxs) var(--mds-spacing-xs);
6
+ border-radius: var(--mds-border-radius-sm);
7
+
8
+ font-family: var(--mds-font-family-base);
9
+ font-weight: var(--mds-font-weight-medium);
10
+ font-size: var(--mds-font-size-paragraph-small);
11
+ line-height: var(--mds-line-height-paragraph-xs);
12
+ letter-spacing: var(--mds-letter-spacing-default);
13
+ white-space: nowrap;
14
+ vertical-align: baseline;
15
+ }
16
+
17
+ .mds-badge--has-icon {
18
+ gap: var(--mds-spacing-xxs);
19
+ }
20
+
21
+ /* Normalize icon dimensions to match the badge icon token across <i> and <svg> usage. */
22
+ .mds-badge > i,
23
+ .mds-badge > svg {
24
+ width: var(--mds-icons-xxs);
25
+ height: var(--mds-icons-xxs);
26
+ font-size: var(--mds-icons-xxs);
27
+ flex-shrink: 0;
28
+ }
29
+
30
+ /* Pill shape overrides the default rounded corners */
31
+ .mds-badge--pill {
32
+ border-radius: var(--mds-border-radius-pill);
33
+ }
34
+
35
+ /*
36
+ * Per-variant colour rules.
37
+ * Default contrast: solid coloured background with inverse text.
38
+ * Subtle contrast (.mds-badge--subtle): light tinted background, dark feedback text, visible border.
39
+ */
40
+
41
+ .mds-badge--subtle {
42
+ border: var(--mds-stroke-weight-sm) solid transparent;
43
+ }
44
+
45
+ /* --- Primary --- */
46
+ .mds-badge--primary {
47
+ background-color: var(--mds-bg-feedback-primary-default);
48
+ color: var(--mds-text-inverse);
49
+ }
50
+
51
+ .mds-badge--primary.mds-badge--subtle {
52
+ background-color: var(--mds-bg-feedback-primary-subtle);
53
+ color: var(--mds-text-feedback-primary);
54
+ border-color: var(--mds-border-feedback-primary);
55
+ }
56
+
57
+ /* --- Secondary --- */
58
+ .mds-badge--secondary {
59
+ background-color: var(--mds-bg-feedback-secondary-default);
60
+ color: var(--mds-text-feedback-secondary);
61
+ }
62
+
63
+ .mds-badge--secondary.mds-badge--subtle {
64
+ background-color: var(--mds-bg-feedback-secondary-subtle);
65
+ color: var(--mds-text-feedback-secondary);
66
+ border-color: var(--mds-border-feedback-secondary);
67
+ }
68
+
69
+ /* --- Success --- */
70
+ .mds-badge--success {
71
+ background-color: var(--mds-bg-feedback-success-default);
72
+ color: var(--mds-text-inverse);
73
+ }
74
+
75
+ .mds-badge--success.mds-badge--subtle {
76
+ background-color: var(--mds-bg-feedback-success-subtle);
77
+ color: var(--mds-text-feedback-success);
78
+ border-color: var(--mds-border-feedback-success);
79
+ }
80
+
81
+ /* --- Danger --- */
82
+ .mds-badge--danger {
83
+ background-color: var(--mds-bg-feedback-danger-default);
84
+ color: var(--mds-text-inverse);
85
+ }
86
+
87
+ .mds-badge--danger.mds-badge--subtle {
88
+ background-color: var(--mds-bg-feedback-danger-subtle);
89
+ color: var(--mds-text-feedback-danger);
90
+ border-color: var(--mds-border-feedback-danger);
91
+ }
92
+
93
+ /* --- Warning --- */
94
+ .mds-badge--warning {
95
+ background-color: var(--mds-bg-feedback-warning-default);
96
+ color: var(--mds-text-feedback-warning);
97
+ }
98
+
99
+ .mds-badge--warning.mds-badge--subtle {
100
+ background-color: var(--mds-bg-feedback-warning-subtle);
101
+ color: var(--mds-text-feedback-warning);
102
+ border-color: var(--mds-border-feedback-warning);
103
+ }
104
+
105
+ /* --- Info --- */
106
+ .mds-badge--info {
107
+ background-color: var(--mds-bg-feedback-info-default);
108
+ color: var(--mds-text-inverse);
109
+ }
110
+
111
+ .mds-badge--info.mds-badge--subtle {
112
+ background-color: var(--mds-bg-feedback-info-subtle);
113
+ color: var(--mds-text-feedback-info);
114
+ border-color: var(--mds-border-feedback-info);
115
+ }
@@ -1,2 +1,2 @@
1
- import { Badge } from "./Badge2.js";
1
+ import { Badge } from "./Badge.js";
2
2
  export { Badge };
@@ -0,0 +1,295 @@
1
+ .mds-btn.btn {
2
+ background-color: var(--mds-bg-interactive-primary-default);
3
+ border: none;
4
+ border-radius: var(--mds-border-radius-sm);
5
+ padding: var(--mds-spacing-xs) var(--mds-spacing-sm);
6
+
7
+ color: var(--mds-text-inverse);
8
+ font-family: var(--mds-font-family-base);
9
+ font-weight: var(--mds-font-weight-regular);
10
+ font-size: var(--mds-font-size-paragraph-default);
11
+ line-height: var(--mds-line-height-paragraph-xs);
12
+ letter-spacing: var(--mds-letter-spacing-default);
13
+
14
+ /* Keep icon/text spacing consistent with icon variants from the design matrix. */
15
+ display: inline-flex;
16
+ align-items: center;
17
+ gap: var(--mds-spacing-xs);
18
+ }
19
+
20
+ /* Icon-only sizing in Figma is not derived from text button size classes. */
21
+ .mds-btn.btn.mds-btn--icon-only {
22
+ padding: var(--mds-spacing-xs);
23
+ border-radius: var(--mds-border-radius-xl);
24
+ }
25
+
26
+ .mds-btn.btn.mds-btn--icon-only i,
27
+ .mds-btn.btn.mds-btn--icon-only svg {
28
+ inline-size: var(--mds-icons-xs);
29
+ block-size: var(--mds-icons-xs);
30
+ font-size: var(--mds-icons-xs);
31
+ line-height: 1;
32
+ flex-shrink: 0;
33
+ }
34
+
35
+ .mds-btn.btn.mds-btn--icon-only.mds-btn--size-sm {
36
+ padding: var(--mds-spacing-xxs);
37
+ }
38
+
39
+ .mds-btn.btn.mds-btn--icon-only.mds-btn--size-sm i,
40
+ .mds-btn.btn.mds-btn--icon-only.mds-btn--size-sm svg {
41
+ inline-size: var(--mds-icons-xxs);
42
+ block-size: var(--mds-icons-xxs);
43
+ font-size: var(--mds-icons-xxs);
44
+ }
45
+
46
+ .mds-btn.btn.mds-btn--icon-only.mds-btn--size-lg {
47
+ padding: var(--mds-spacing-xs);
48
+ border-radius: var(--mds-border-radius-sm);
49
+ }
50
+
51
+ .mds-btn.btn.mds-btn--size-sm i,
52
+ .mds-btn.btn.mds-btn--size-sm svg {
53
+ inline-size: var(--mds-icons-xxs);
54
+ block-size: var(--mds-icons-xxs);
55
+ font-size: var(--mds-icons-xxs);
56
+ line-height: 1;
57
+ flex-shrink: 0;
58
+ }
59
+
60
+ .mds-btn.btn.mds-btn--size-md i,
61
+ .mds-btn.btn.mds-btn--size-md svg,
62
+ .mds-btn.btn.mds-btn--size-lg i,
63
+ .mds-btn.btn.mds-btn--size-lg svg {
64
+ inline-size: var(--mds-icons-xs);
65
+ block-size: var(--mds-icons-xs);
66
+ font-size: var(--mds-icons-xs);
67
+ line-height: 1;
68
+ flex-shrink: 0;
69
+ }
70
+
71
+ .mds-btn.btn:focus {
72
+ box-shadow: none;
73
+ outline: none;
74
+ }
75
+ .mds-btn.btn:focus-visible {
76
+ outline: var(--mds-stroke-weight-md) solid var(--mds-focus-default);
77
+ outline-offset: var(--mds-spacing-offset);
78
+ box-shadow: none;
79
+ }
80
+ .mds-btn.btn:active:focus-visible {
81
+ box-shadow: none;
82
+ }
83
+ .mds-btn.btn.btn-danger:focus-visible,
84
+ .mds-btn.btn.btn-outline-danger:focus-visible {
85
+ outline: var(--mds-stroke-weight-md) solid var(--mds-focus-danger);
86
+ }
87
+ .mds-btn.btn:hover {
88
+ background-color: var(--mds-bg-interactive-primary-hover);
89
+ }
90
+ .mds-btn.btn:active {
91
+ background-color: var(--mds-bg-interactive-primary-active);
92
+ box-shadow: none;
93
+ }
94
+ .mds-btn.btn:disabled {
95
+ background-color: var(--mds-bg-interactive-primary-disabled);
96
+ }
97
+
98
+ /**
99
+ * Secondary variants
100
+ */
101
+ .mds-btn.btn.btn-secondary {
102
+ background-color: var(--mds-bg-interactive-secondary-default);
103
+ color: var(--mds-text-subtle);
104
+ }
105
+ .mds-btn.btn.btn-secondary:hover {
106
+ background-color: var(--mds-bg-interactive-secondary-hover);
107
+ }
108
+ .mds-btn.btn.btn-secondary:active {
109
+ background-color: var(--mds-bg-interactive-secondary-active);
110
+ }
111
+ .mds-btn.btn.btn-secondary:disabled {
112
+ background-color: var(--mds-bg-interactive-secondary-disabled);
113
+ color: var(--mds-text-muted);
114
+ }
115
+
116
+ /**
117
+ * Danger variants
118
+ */
119
+ .mds-btn.btn-danger {
120
+ background-color: var(--mds-bg-interactive-danger-default);
121
+ }
122
+ .mds-btn.btn-danger:hover {
123
+ background-color: var(--mds-bg-interactive-danger-hover);
124
+ }
125
+ .mds-btn.btn-danger:active {
126
+ background-color: var(--mds-bg-interactive-danger-active);
127
+ }
128
+ .mds-btn.btn.btn-danger:disabled {
129
+ background-color: var(--mds-bg-interactive-danger-disabled);
130
+ }
131
+
132
+ /**
133
+ * Ghost variants
134
+ */
135
+ .mds-btn.btn.btn-ghost {
136
+ background-color: transparent;
137
+ color: var(--mds-text-subtle);
138
+ }
139
+ .mds-btn.btn.btn-ghost:hover {
140
+ background-color: var(--mds-bg-interactive-secondary-hover);
141
+ color: var(--mds-text-subtle);
142
+ }
143
+ .mds-btn.btn.btn-ghost:active {
144
+ background-color: var(--mds-bg-interactive-secondary-active);
145
+ color: var(--mds-text-subtle);
146
+ }
147
+ .mds-btn.btn.btn-ghost:disabled {
148
+ background-color: transparent;
149
+ color: var(--mds-text-muted);
150
+ }
151
+
152
+ /**
153
+ * Outline Primary variants
154
+ */
155
+ .mds-btn.btn:is(
156
+ .btn-outline-primary,
157
+ .btn-outline-secondary,
158
+ .btn-outline-danger
159
+ ) {
160
+ background-color: transparent;
161
+ border: var(--mds-stroke-weight-sm) solid transparent;
162
+ }
163
+
164
+ .mds-btn.btn.btn-outline-primary {
165
+ border-color: var(--mds-border-interactive-primary-default);
166
+ color: var(--mds-text-link-primary-default);
167
+ }
168
+ .mds-btn.btn-outline-primary:hover {
169
+ border-color: var(--mds-bg-interactive-primary-hover);
170
+ background-color: var(--mds-bg-interactive-primary-hover);
171
+ color: var(--mds-text-inverse);
172
+ }
173
+ .mds-btn.btn-outline-primary:active {
174
+ border-color: var(--mds-bg-interactive-primary-active);
175
+ background-color: var(--mds-bg-interactive-primary-active);
176
+ color: var(--mds-text-inverse);
177
+ }
178
+ .mds-btn.btn.btn-outline-primary:disabled {
179
+ border-color: var(--mds-border-interactive-primary-disabled);
180
+ color: var(--mds-text-link-primary-disabled);
181
+ }
182
+
183
+ /**
184
+ * Outline Secondary variants
185
+ */
186
+ .mds-btn.btn.btn-outline-secondary {
187
+ border-color: var(--mds-border-interactive-secondary-default);
188
+ color: var(--mds-text-subtle);
189
+ }
190
+ .mds-btn.btn-outline-secondary:hover {
191
+ border-color: var(--mds-border-interactive-secondary-hover);
192
+ background-color: var(--mds-border-interactive-secondary-hover);
193
+ color: var(--mds-text-inverse);
194
+ }
195
+ .mds-btn.btn-outline-secondary:active {
196
+ border-color: var(--mds-border-interactive-secondary-active);
197
+ background-color: var(--mds-border-interactive-secondary-active);
198
+ color: var(--mds-text-inverse);
199
+ }
200
+ .mds-btn.btn.btn-outline-secondary:disabled {
201
+ border-color: var(--mds-border-interactive-secondary-disabled);
202
+ color: var(--mds-text-muted);
203
+ }
204
+
205
+ /**
206
+ * Outline Danger variants
207
+ */
208
+ .mds-btn.btn.btn-outline-danger {
209
+ border-color: var(--mds-border-interactive-danger-default);
210
+ color: var(--mds-text-danger);
211
+ }
212
+ .mds-btn.btn-outline-danger:hover {
213
+ border-color: var(--mds-bg-interactive-danger-hover);
214
+ background-color: var(--mds-bg-interactive-danger-hover);
215
+ color: var(--mds-text-inverse);
216
+ }
217
+ .mds-btn.btn-outline-danger:active {
218
+ border-color: var(--mds-bg-interactive-danger-active);
219
+ background-color: var(--mds-bg-interactive-danger-active);
220
+ color: var(--mds-text-inverse);
221
+ }
222
+ .mds-btn.btn.btn-outline-danger:disabled {
223
+ border-color: var(--mds-border-interactive-danger-disabled);
224
+ color: var(--mds-text-danger-disabled);
225
+ }
226
+
227
+ /**
228
+ * Size variants
229
+ */
230
+ .mds-btn.mds-btn--size-sm {
231
+ padding: var(--mds-spacing-xxs) var(--mds-spacing-xs);
232
+ border-radius: var(--mds-border-radius-xs);
233
+ font-weight: var(--mds-font-weight-medium);
234
+ font-size: var(--mds-font-size-paragraph-small);
235
+ }
236
+ .mds-btn.mds-btn--size-md {
237
+ padding: var(--mds-spacing-xs) var(--mds-spacing-sm);
238
+ font-size: var(--mds-font-size-paragraph-default);
239
+ }
240
+ .mds-btn.mds-btn--size-lg {
241
+ padding: var(--mds-spacing-sm) var(--mds-spacing-md);
242
+ font-size: var(--mds-font-size-paragraph-default);
243
+ }
244
+
245
+ /* Keep outer geometry aligned with filled variants when outline border is present. */
246
+ .mds-btn.mds-btn--size-sm:is(
247
+ .btn-outline-primary,
248
+ .btn-outline-secondary,
249
+ .btn-outline-danger
250
+ ) {
251
+ padding: calc(var(--mds-spacing-xxs) - var(--mds-stroke-weight-sm))
252
+ calc(var(--mds-spacing-xs) - var(--mds-stroke-weight-sm));
253
+ }
254
+
255
+ .mds-btn.mds-btn--size-md:is(
256
+ .btn-outline-primary,
257
+ .btn-outline-secondary,
258
+ .btn-outline-danger
259
+ ) {
260
+ padding: calc(var(--mds-spacing-xs) - var(--mds-stroke-weight-sm))
261
+ calc(var(--mds-spacing-sm) - var(--mds-stroke-weight-sm));
262
+ }
263
+
264
+ .mds-btn.mds-btn--size-lg:is(
265
+ .btn-outline-primary,
266
+ .btn-outline-secondary,
267
+ .btn-outline-danger
268
+ ) {
269
+ padding: calc(var(--mds-spacing-sm) - var(--mds-stroke-weight-sm))
270
+ calc(var(--mds-spacing-md) - var(--mds-stroke-weight-sm));
271
+ }
272
+
273
+ .mds-btn.mds-btn--icon-only:is(
274
+ .btn-outline-primary,
275
+ .btn-outline-secondary,
276
+ .btn-outline-danger
277
+ ) {
278
+ padding: calc(var(--mds-spacing-xs) - var(--mds-stroke-weight-sm));
279
+ }
280
+
281
+ .mds-btn.mds-btn--icon-only.mds-btn--size-sm:is(
282
+ .btn-outline-primary,
283
+ .btn-outline-secondary,
284
+ .btn-outline-danger
285
+ ) {
286
+ padding: calc(var(--mds-spacing-xxs) - var(--mds-stroke-weight-sm));
287
+ }
288
+
289
+ .mds-btn.mds-btn--icon-only.mds-btn--size-lg:is(
290
+ .btn-outline-primary,
291
+ .btn-outline-secondary,
292
+ .btn-outline-danger
293
+ ) {
294
+ padding: calc(var(--mds-spacing-xs) - var(--mds-stroke-weight-sm));
295
+ }