@hashicorp/design-system-components 4.24.1 → 4.24.2-rc-20251110174309

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.
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+ import Component from '@glimmer/component';
6
+ import type { HdsDropdownSignature } from '../dropdown/index.ts';
7
+ import type { HdsDropdownToggleButtonSignature } from '../dropdown/toggle/button.ts';
8
+ import type { HdsIconSignature } from '../icon/index.ts';
9
+ import type HdsThemingService from '../../../services/hds-theming.ts';
10
+ import type { HdsThemes, OnSetThemeCallback } from '../../../services/hds-theming.ts';
11
+ interface ThemeOption {
12
+ theme: HdsThemes | undefined;
13
+ icon: HdsIconSignature['Args']['name'];
14
+ label: string;
15
+ }
16
+ interface HdsThemeSwitcherSignature {
17
+ Args: {
18
+ toggleSize?: HdsDropdownToggleButtonSignature['Args']['size'];
19
+ toggleIsFullWidth?: HdsDropdownToggleButtonSignature['Args']['isFullWidth'];
20
+ hasDefaultOption?: boolean;
21
+ hasSystemOption?: boolean;
22
+ onSetTheme?: OnSetThemeCallback;
23
+ };
24
+ Element: HdsDropdownSignature['Element'];
25
+ }
26
+ export default class HdsThemeSwitcher extends Component<HdsThemeSwitcherSignature> {
27
+ readonly hdsTheming: HdsThemingService;
28
+ get toggleSize(): "small" | "medium";
29
+ get toggleIsFullWidth(): boolean;
30
+ get toggleContent(): {
31
+ label: string;
32
+ icon: "type" | "map" | "filter" | "code" | "link" | "menu" | "search" | "video" | "circle" | "image" | "path" | "tag" | "repeat" | "hash" | "queue" | "shuffle" | "chevron-up" | "chevron-down" | "unfold-open" | "unfold-close" | "arrow-down" | "arrow-up" | "swap-vertical" | "top" | "key" | "move" | "change" | "pause" | "play" | "move-horizontal" | "loading" | "loading-static" | "running" | "running-static" | "apple" | "apple-color" | "alibaba" | "alibaba-color" | "amazon-ecs" | "amazon-ecs-color" | "amazon-eks" | "amazon-eks-color" | "auth0" | "auth0-color" | "aws" | "aws-color" | "aws-cdk" | "aws-cdk-color" | "aws-cloudwatch" | "aws-cloudwatch-color" | "aws-ec2" | "aws-ec2-color" | "aws-lambda" | "aws-lambda-color" | "aws-s3" | "aws-s3-color" | "azure" | "azure-color" | "azure-aks" | "azure-aks-color" | "azure-blob-storage" | "azure-blob-storage-color" | "azure-devops" | "azure-devops-color" | "azure-vms" | "azure-vms-color" | "bitbucket" | "bitbucket-color" | "bridgecrew" | "bridgecrew-color" | "cisco" | "cisco-color" | "codepen" | "codepen-color" | "confluence" | "confluence-color" | "confluent" | "confluent-color" | "datadog" | "datadog-color" | "digital-ocean" | "digital-ocean-color" | "docker" | "docker-color" | "duo" | "duo-color" | "elastic-observability" | "elastic-observability-color" | "f5" | "f5-color" | "facebook" | "facebook-color" | "figma" | "figma-color" | "gcp" | "gcp-color" | "git" | "git-color" | "gitlab" | "gitlab-color" | "github" | "github-color" | "google" | "google-color" | "google-docs" | "google-docs-color" | "google-drive" | "google-drive-color" | "google-forms" | "google-forms-color" | "google-sheets" | "google-sheets-color" | "google-slides" | "google-slides-color" | "grafana" | "grafana-color" | "helm" | "helm-color" | "infracost" | "infracost-color" | "jenkins" | "jenkins-color" | "jfrog" | "jfrog-color" | "jira" | "jira-color" | "jwt" | "jwt-color" | "kubernetes" | "kubernetes-color" | "lightlytics" | "lightlytics-color" | "linkedin" | "linkedin-color" | "linode" | "linode-color" | "linux" | "linux-color" | "loom" | "loom-color" | "meetup" | "meetup-color" | "microsoft" | "microsoft-color" | "microsoft-teams" | "microsoft-teams-color" | "minio" | "minio-color" | "mongodb" | "mongodb-color" | "new-relic" | "new-relic-color" | "okta" | "okta-color" | "oracle" | "oracle-color" | "opa" | "opa-color" | "openid" | "openid-color" | "openstack" | "openstack-color" | "pack" | "pack-color" | "pager-duty" | "pager-duty-color" | "ping-identity " | "ping-identity-color" | "postgres" | "postgres-color" | "rabbitmq" | "rabbitmq-color" | "saml" | "saml-color" | "service-now" | "service-now-color" | "slack" | "slack-color" | "snyk" | "snyk-color" | "splunk" | "splunk-color" | "twilio" | "twilio-color" | "twitch" | "twitch-color" | "twitter" | "twitter-color" | "twitter-x" | "twitter-x-color" | "vantage" | "vantage-color" | "venafi" | "venafi-color" | "vercel" | "vercel-color" | "vmware" | "vmware-color" | "youtube" | "youtube-color" | "boundary" | "boundary-color" | "boundary-fill" | "boundary-fill-color" | "boundary-square" | "boundary-square-color" | "consul" | "consul-color" | "consul-fill" | "consul-fill-color" | "consul-square" | "consul-square-color" | "nomad" | "nomad-color" | "nomad-fill" | "nomad-fill-color" | "nomad-square" | "nomad-square-color" | "packer" | "packer-color" | "packer-fill" | "packer-fill-color" | "packer-square" | "packer-square-color" | "terraform" | "terraform-color" | "terraform-fill" | "terraform-fill-color" | "terraform-square" | "terraform-square-color" | "vagrant" | "vagrant-color" | "vagrant-fill" | "vagrant-fill-color" | "vagrant-square" | "vagrant-square-color" | "vault" | "vault-color" | "vault-fill" | "vault-fill-color" | "vault-square" | "vault-square-color" | "vault-radar" | "vault-radar-color" | "vault-radar-fill" | "vault-radar-fill-color" | "vault-radar-square" | "vault-radar-square-color" | "vault-secrets" | "vault-secrets-color" | "vault-secrets-fill" | "vault-secrets-fill-color" | "vault-secrets-square" | "vault-secrets-square-color" | "waypoint" | "waypoint-color" | "waypoint-fill" | "waypoint-fill-color" | "waypoint-square" | "waypoint-square-color" | "hashicorp" | "hashicorp-color" | "hashicorp-fill" | "hashicorp-fill-color" | "hashicorp-square" | "hashicorp-square-color" | "hcp" | "hcp-color" | "hcp-fill" | "hcp-fill-color" | "hcp-square" | "hcp-square-color" | "accessibility" | "folder-users" | "frown" | "identity-service" | "identity-user" | "meh" | "robot" | "smile" | "user" | "user-check" | "user-circle" | "user-circle-fill" | "user-minus" | "user-plus" | "user-x" | "users" | "ampersand" | "beaker" | "bucket" | "bulb" | "circle-dot" | "circle-fill" | "circle-half" | "diamond" | "diamond-fill" | "disc" | "dot" | "dot-half" | "droplet" | "flag" | "gift" | "government" | "handshake" | "hexagon" | "hexagon-fill" | "labyrinth" | "layers" | "moon" | "octagon" | "outline" | "random" | "rocket" | "sparkle" | "square" | "square-fill" | "sun" | "triangle" | "triangle-fill" | "truck" | "wand" | "zap" | "zap-off" | "docs" | "docs-download" | "docs-link" | "guide" | "guide-link" | "help" | "info" | "info-fill" | "learn" | "learn-link" | "support" | "alert-circle" | "alert-circle-fill" | "alert-diamond" | "alert-diamond-fill" | "alert-octagon" | "alert-octagon-fill" | "alert-triangle" | "alert-triangle-fill" | "check" | "check-circle" | "check-circle-fill" | "check-diamond" | "check-diamond-fill" | "check-hexagon" | "check-hexagon-fill" | "check-square" | "check-square-fill" | "skip" | "x" | "x-circle" | "x-circle-fill" | "x-diamond" | "x-diamond-fill" | "x-hexagon" | "x-hexagon-fill" | "x-square" | "x-square-fill" | "bug" | "certificate" | "eye" | "eye-off" | "fingerprint" | "keychain" | "lock" | "lock-fill" | "lock-off" | "shield" | "shield-alert" | "shield-check" | "shield-off" | "shield-x" | "token" | "unlock" | "verified" | "wall" | "minus" | "minus-circle" | "minus-circle-fill" | "minus-plus" | "minus-plus-circle" | "minus-plus-square" | "minus-square" | "minus-square-fill" | "plus" | "plus-circle" | "plus-circle-fill" | "plus-square" | "camera" | "camera-off" | "cast" | "closed-caption" | "fast-forward" | "film" | "headphones" | "music" | "pause-circle" | "play-circle" | "radio" | "rewind" | "rss" | "skip-back" | "skip-forward" | "speaker" | "stop-circle" | "volume" | "volume-down" | "volume-up" | "volume-x" | "wifi" | "wifi-off" | "compass" | "crosshair" | "map-pin" | "navigation" | "navigation-alt" | "redirect" | "target" | "align-center" | "align-justify" | "align-left" | "align-right" | "battery" | "battery-charging" | "bookmark" | "bookmark-add" | "bookmark-add-fill" | "bookmark-fill" | "bookmark-remove" | "bookmark-remove-fill" | "bottom" | "start" | "end" | "command" | "crop" | "dashboard" | "delete" | "download" | "edit" | "entry-point" | "exit-point" | "external-link" | "filter-circle" | "filter-fill" | "grid" | "grid-alt" | "home" | "jump-link" | "layout" | "list" | "maximize" | "maximize-alt" | "minimize" | "minimize-alt" | "more-horizontal" | "more-vertical" | "mouse-pointer" | "paperclip" | "pen-tool" | "pencil-tool" | "pin" | "pin-off" | "power" | "printer" | "reload" | "resize-column" | "rotate-cw" | "rotate-ccw" | "share" | "sidebar" | "sidebar-hide" | "sidebar-show" | "sign-in" | "sign-out" | "slash" | "slash-square" | "sort-asc" | "sort-desc" | "switcher" | "sync" | "sync-alert" | "sync-reverse" | "toggle-left" | "toggle-right" | "trash" | "text-wrap" | "upload" | "zoom-in" | "zoom-out" | "archive" | "clipboard" | "clipboard-checked" | "clipboard-copy" | "clipboard-x" | "file" | "file-change" | "file-check" | "file-diff" | "file-minus" | "file-plus" | "file-source" | "file-text" | "file-x" | "files" | "folder" | "folder-fill" | "folder-minus" | "folder-minus-fill" | "folder-plus" | "folder-plus-fill" | "folder-star" | "inbox" | "api" | "auto-apply" | "build" | "change-circle" | "change-square" | "channel" | "cloud" | "cloud-check" | "cloud-download" | "cloud-lightning" | "cloud-lock" | "cloud-off" | "cloud-upload" | "cloud-x" | "connection" | "connection-gateway" | "cpu" | "duplicate" | "gateway" | "git-branch" | "git-commit" | "git-merge" | "git-pull-request" | "git-repo" | "hammer" | "key-values" | "mainframe" | "mesh" | "module" | "monitor" | "network" | "network-alt" | "node" | "pipeline" | "plug" | "replication-direct" | "replication-perf" | "scissors" | "server" | "server-cluster" | "serverless" | "service" | "settings" | "sliders" | "smartphone" | "socket" | "step" | "tablet" | "terminal" | "terminal-screen" | "test" | "tools" | "transform-data" | "tv" | "webhook" | "wrench" | "calendar" | "clock" | "clock-filled" | "delay" | "event" | "history" | "hourglass" | "watch" | "bar-chart" | "bar-chart-alt" | "box" | "collections" | "database" | "hard-drive" | "line-chart" | "line-chart-up" | "logs" | "package" | "pie-chart" | "save" | "trend-down" | "trend-up" | "activity" | "at-sign" | "award" | "bell" | "bell-active" | "bell-active-fill" | "bell-off" | "discussion-circle" | "discussion-square" | "heart" | "heart-fill" | "heart-off" | "mail" | "mail-open" | "message-circle" | "message-circle-fill" | "message-square" | "message-square-fill" | "mic" | "mic-off" | "newspaper" | "phone" | "phone-call" | "phone-off" | "send" | "star" | "star-circle" | "star-fill" | "star-off" | "thumbs-down" | "thumbs-up" | "video-off" | "bank-vault" | "briefcase" | "credit-card" | "dollar-sign" | "enterprise" | "globe" | "globe-private" | "org" | "provider" | "shopping-bag" | "shopping-cart" | "arrow-down-circle" | "arrow-down-left" | "arrow-down-right" | "arrow-left" | "arrow-left-circle" | "arrow-right" | "arrow-right-circle" | "arrow-up-circle" | "arrow-up-left" | "arrow-up-right" | "caret" | "chevron-left" | "chevron-right" | "chevrons-down" | "chevrons-left" | "chevrons-right" | "chevrons-up" | "corner-down-left" | "corner-down-right" | "corner-left-down" | "corner-left-up" | "corner-right-down" | "corner-right-up" | "corner-up-left" | "corner-up-right" | "load-balancer" | "migrate" | "swap-horizontal";
33
+ } | {
34
+ label: string;
35
+ icon: undefined;
36
+ };
37
+ get hasDefaultOption(): boolean;
38
+ get hasSystemOption(): boolean;
39
+ get _options(): Partial<Record<"default" | "light" | "dark" | "system", ThemeOption>>;
40
+ get currentTheme(): "default" | "light" | "dark" | "system" | undefined;
41
+ onSelectTheme(theme: HdsThemes | undefined): void;
42
+ }
43
+ export {};
@@ -223,6 +223,7 @@ export { default as HdsTextBody } from './components/hds/text/body.ts';
223
223
  export { default as HdsTextCode } from './components/hds/text/code.ts';
224
224
  export { default as HdsTextDisplay } from './components/hds/text/display.ts';
225
225
  export * from './components/hds/text/types.ts';
226
+ export { default as HdsThemeSwitcher } from './components/hds/theme-switcher/index.ts';
226
227
  export { default as HdsTime } from './components/hds/time/index.ts';
227
228
  export { default as HdsTimeSingle } from './components/hds/time/single.ts';
228
229
  export { default as HdsTimeRange } from './components/hds/time/range.ts';
@@ -0,0 +1,69 @@
1
+ import Service from '@ember/service';
2
+ export declare enum HdsThemeValues {
3
+ Default = "default",
4
+ System = "system",
5
+ Light = "light",
6
+ Dark = "dark"
7
+ }
8
+ declare enum HdsModesBaseValues {
9
+ Default = "default"
10
+ }
11
+ declare enum HdsModesLightValues {
12
+ CdsG0 = "cds-g0",
13
+ CdsG10 = "cds-g10"
14
+ }
15
+ declare enum HdsModesDarkValues {
16
+ CdsG90 = "cds-g90",
17
+ CdsG100 = "cds-g100"
18
+ }
19
+ export declare enum HdsCssSelectorsValues {
20
+ Data = "data",
21
+ Class = "class"
22
+ }
23
+ export type HdsThemes = `${HdsThemeValues}`;
24
+ export type HdsModes = `${HdsModesBaseValues}` | `${HdsModesLightValues}` | `${HdsModesDarkValues}`;
25
+ export type HdsModesLight = `${HdsModesLightValues}`;
26
+ export type HdsModesDark = `${HdsModesDarkValues}`;
27
+ export type HdsCssSelectors = `${HdsCssSelectorsValues}`;
28
+ type HdsThemingOptions = {
29
+ lightTheme: HdsModesLight;
30
+ darkTheme: HdsModesDark;
31
+ cssSelector: HdsCssSelectors;
32
+ isComplex: boolean;
33
+ };
34
+ type SetThemeArgs = {
35
+ theme: HdsThemes | undefined;
36
+ options?: HdsThemingOptions;
37
+ onSetTheme?: OnSetThemeCallback;
38
+ };
39
+ export type OnSetThemeCallbackArgs = {
40
+ currentTheme: HdsThemes | undefined;
41
+ currentMode: HdsModes | undefined;
42
+ };
43
+ export type OnSetThemeCallback = (args: OnSetThemeCallbackArgs) => void;
44
+ export declare const THEMES: HdsThemes[];
45
+ export declare const MODES_LIGHT: HdsModesLight[];
46
+ export declare const MODES_DARK: HdsModesDark[];
47
+ export declare const MODES: HdsModes[];
48
+ export declare const HDS_THEMING_DATA_SELECTOR = "data-hds-theme";
49
+ export declare const HDS_THEMING_CLASS_SELECTOR_PREFIX = "hds-theme";
50
+ export declare const HDS_THEMING_LOCALSTORAGE_DATA = "hds-theming-data";
51
+ export declare const DEFAULT_THEMING_OPTION_LIGHT_THEME = HdsModesLightValues.CdsG0;
52
+ export declare const DEFAULT_THEMING_OPTION_DARK_THEME = HdsModesDarkValues.CdsG100;
53
+ export declare const DEFAULT_THEMING_OPTION_CSS_SELECTOR = "data";
54
+ export default class HdsThemingService extends Service {
55
+ _currentTheme: HdsThemes | undefined;
56
+ _currentMode: HdsModes | undefined;
57
+ _currentLightTheme: HdsModesLight;
58
+ _currentDarkTheme: HdsModesDark;
59
+ _currentCssSelector: HdsCssSelectors;
60
+ globalOnSetTheme: OnSetThemeCallback | undefined;
61
+ initializeTheme(): void;
62
+ setTheme({ theme, options, onSetTheme }: SetThemeArgs): void;
63
+ get currentTheme(): HdsThemes | undefined;
64
+ get currentMode(): HdsModes | undefined;
65
+ get currentLightTheme(): HdsModesLight;
66
+ get currentDarkTheme(): HdsModesDark;
67
+ get currentCssSelector(): HdsCssSelectors;
68
+ }
69
+ export {};
@@ -2,3 +2,4 @@
2
2
  * Copyright (c) HashiCorp, Inc.
3
3
  * SPDX-License-Identifier: MPL-2.0
4
4
  */
5
+ export * from './services/hds-theming.ts';
@@ -226,6 +226,7 @@ import type HdsTagComponent from './components/hds/tag';
226
226
  import type HdsTooltipButtonComponent from './components/hds/tooltip-button';
227
227
  import type HdsToastComponent from './components/hds/toast';
228
228
  import type HdsTextCodeComponent from './components/hds/text/code';
229
+ import type HdsThemeSwitcherComponent from './components/hds/theme-switcher';
229
230
  import type HdsTimeComponent from './components/hds/time';
230
231
  import type HdsTimeSingleComponent from './components/hds/time/single';
231
232
  import type HdsTimeRangeComponent from './components/hds/time/range';
@@ -717,6 +718,8 @@ export default interface HdsComponentsRegistry {
717
718
  'hds/tooltip-button': typeof HdsTooltipButtonComponent;
718
719
  'Hds::Toast': typeof HdsToastComponent;
719
720
  'hds/toast': typeof HdsToastComponent;
721
+ 'Hds::ThemeSwitcher': typeof HdsThemeSwitcherComponent;
722
+ 'hds/theme-switcher': typeof HdsThemeSwitcherComponent;
720
723
  'Hds::Time': typeof HdsTimeComponent;
721
724
  'hds/time': typeof HdsTimeComponent;
722
725
  'Hds::Time::Single': typeof HdsTimeSingleComponent;
@@ -0,0 +1 @@
1
+ export { default } from "@hashicorp/design-system-components/components/hds/theme-switcher/index";
@@ -0,0 +1 @@
1
+ export { default } from "@hashicorp/design-system-components/services/hds-theming";
@@ -0,0 +1,100 @@
1
+ import Component from '@glimmer/component';
2
+ import { inject } from '@ember/service';
3
+ import { action } from '@ember/object';
4
+ import { precompileTemplate } from '@ember/template-compilation';
5
+ import { g, i, n } from 'decorator-transforms/runtime';
6
+ import { setComponentTemplate } from '@ember/component';
7
+
8
+ var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n\n{{!\n ------------------------------------------------------------------------------------------\n IMPORTANT: this is a temporary implementation, while we wait for the design specifications\n ------------------------------------------------------------------------------------------\n}}\n\n<Hds::Dropdown\n @enableCollisionDetection={{true}}\n @matchToggleWidth={{@toggleIsFullWidth}}\n class=\"hds-theme-switcher-control\"\n ...attributes\n as |D|\n>\n <D.ToggleButton\n @color=\"secondary\"\n @size={{this.toggleSize}}\n @isFullWidth={{this.toggleIsFullWidth}}\n @text={{this.toggleContent.label}}\n @icon={{this.toggleContent.icon}}\n />\n {{#each-in this._options as |key data|}}\n <D.Interactive @icon={{data.icon}} {{on \"click\" (fn this.onSelectTheme data.theme)}}>{{data.label}}</D.Interactive>\n {{/each-in}}\n</Hds::Dropdown>");
9
+
10
+ /**
11
+ * Copyright (c) HashiCorp, Inc.
12
+ * SPDX-License-Identifier: MPL-2.0
13
+ */
14
+
15
+ const OPTIONS = {
16
+ default: {
17
+ theme: 'default',
18
+ icon: 'hashicorp',
19
+ label: 'Default'
20
+ },
21
+ system: {
22
+ theme: 'system',
23
+ icon: 'monitor',
24
+ label: 'System'
25
+ },
26
+ light: {
27
+ theme: 'light',
28
+ icon: 'sun',
29
+ label: 'Light'
30
+ },
31
+ dark: {
32
+ theme: 'dark',
33
+ icon: 'moon',
34
+ label: 'Dark'
35
+ }
36
+ };
37
+ class HdsThemeSwitcher extends Component {
38
+ static {
39
+ g(this.prototype, "hdsTheming", [inject]);
40
+ }
41
+ #hdsTheming = (i(this, "hdsTheming"), void 0);
42
+ get toggleSize() {
43
+ return this.args.toggleSize ?? 'small';
44
+ }
45
+ get toggleIsFullWidth() {
46
+ return this.args.toggleIsFullWidth ?? false;
47
+ }
48
+ get toggleContent() {
49
+ if (this.currentTheme === 'default' && this.hasDefaultOption || this.currentTheme === 'system' && this.hasSystemOption || this.currentTheme === 'light' || this.currentTheme === 'dark') {
50
+ return {
51
+ label: OPTIONS[this.currentTheme].label,
52
+ icon: OPTIONS[this.currentTheme].icon
53
+ };
54
+ } else {
55
+ return {
56
+ label: 'Theme',
57
+ icon: undefined
58
+ };
59
+ }
60
+ }
61
+
62
+ // note: we will use the `default` option in development, while migrating to the `cds` theming
63
+ // during this process, consumers will enable/disable this option via code logic or feature flag
64
+ get hasDefaultOption() {
65
+ return this.args.hasDefaultOption ?? false;
66
+ }
67
+ get hasSystemOption() {
68
+ return this.args.hasSystemOption ?? true;
69
+ }
70
+ get _options() {
71
+ const options = {
72
+ ...OPTIONS
73
+ };
74
+ if (!this.hasDefaultOption) {
75
+ delete options.default;
76
+ }
77
+ if (!this.hasSystemOption) {
78
+ delete options.system;
79
+ }
80
+ return options;
81
+ }
82
+ get currentTheme() {
83
+ // we get the theme from the global service
84
+ return this.hdsTheming.currentTheme;
85
+ }
86
+ onSelectTheme(theme) {
87
+ // we set the theme in the global service (and provide an optional user-defined callback)
88
+ this.hdsTheming.setTheme({
89
+ theme,
90
+ onSetTheme: this.args.onSetTheme
91
+ });
92
+ }
93
+ static {
94
+ n(this.prototype, "onSelectTheme", [action]);
95
+ }
96
+ }
97
+ setComponentTemplate(TEMPLATE, HdsThemeSwitcher);
98
+
99
+ export { HdsThemeSwitcher as default };
100
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/hds/theme-switcher/index.ts"],"sourcesContent":["/**\n * Copyright (c) HashiCorp, Inc.\n * SPDX-License-Identifier: MPL-2.0\n */\n\n// ------------------------------------------------------------------------------------------\n// IMPORTANT: this is a temporary implementation, while we wait for the design specifications\n// ------------------------------------------------------------------------------------------\n\nimport Component from '@glimmer/component';\nimport { inject as service } from '@ember/service';\nimport { action } from '@ember/object';\n\nimport type { HdsDropdownSignature } from '../dropdown/index.ts';\nimport type { HdsDropdownToggleButtonSignature } from '../dropdown/toggle/button.ts';\nimport type { HdsIconSignature } from '../icon/index.ts';\nimport type HdsThemingService from '../../../services/hds-theming.ts';\nimport type {\n HdsThemes,\n OnSetThemeCallback,\n} from '../../../services/hds-theming.ts';\n\ninterface ThemeOption {\n theme: HdsThemes | undefined;\n icon: HdsIconSignature['Args']['name'];\n label: string;\n}\n\nconst OPTIONS: Record<HdsThemes, ThemeOption> = {\n default: { theme: 'default', icon: 'hashicorp', label: 'Default' },\n system: { theme: 'system', icon: 'monitor', label: 'System' },\n light: { theme: 'light', icon: 'sun', label: 'Light' },\n dark: { theme: 'dark', icon: 'moon', label: 'Dark' },\n};\n\ninterface HdsThemeSwitcherSignature {\n Args: {\n toggleSize?: HdsDropdownToggleButtonSignature['Args']['size'];\n toggleIsFullWidth?: HdsDropdownToggleButtonSignature['Args']['isFullWidth'];\n hasDefaultOption?: boolean;\n hasSystemOption?: boolean;\n onSetTheme?: OnSetThemeCallback;\n };\n Element: HdsDropdownSignature['Element'];\n}\n\nexport default class HdsThemeSwitcher extends Component<HdsThemeSwitcherSignature> {\n @service declare readonly hdsTheming: HdsThemingService;\n\n get toggleSize() {\n return this.args.toggleSize ?? 'small';\n }\n\n get toggleIsFullWidth() {\n return this.args.toggleIsFullWidth ?? false;\n }\n\n get toggleContent() {\n if (\n (this.currentTheme === 'default' && this.hasDefaultOption) ||\n (this.currentTheme === 'system' && this.hasSystemOption) ||\n this.currentTheme === 'light' ||\n this.currentTheme === 'dark'\n ) {\n return {\n label: OPTIONS[this.currentTheme].label,\n icon: OPTIONS[this.currentTheme].icon,\n };\n } else {\n return { label: 'Theme', icon: undefined };\n }\n }\n\n // note: we will use the `default` option in development, while migrating to the `cds` theming\n // during this process, consumers will enable/disable this option via code logic or feature flag\n get hasDefaultOption() {\n return this.args.hasDefaultOption ?? false;\n }\n\n get hasSystemOption() {\n return this.args.hasSystemOption ?? true;\n }\n\n get _options() {\n const options: Partial<typeof OPTIONS> = { ...OPTIONS };\n\n if (!this.hasDefaultOption) {\n delete options.default;\n }\n\n if (!this.hasSystemOption) {\n delete options.system;\n }\n\n return options;\n }\n\n get currentTheme() {\n // we get the theme from the global service\n return this.hdsTheming.currentTheme;\n }\n\n @action\n onSelectTheme(theme: HdsThemes | undefined): void {\n // we set the theme in the global service (and provide an optional user-defined callback)\n this.hdsTheming.setTheme({ theme, onSetTheme: this.args.onSetTheme });\n }\n}\n"],"names":["OPTIONS","default","theme","icon","label","system","light","dark","HdsThemeSwitcher","Component","g","prototype","service","i","void 0","toggleSize","args","toggleIsFullWidth","toggleContent","currentTheme","hasDefaultOption","hasSystemOption","undefined","_options","options","hdsTheming","onSelectTheme","setTheme","onSetTheme","n","action","setComponentTemplate","TEMPLATE"],"mappings":"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"}
@@ -219,6 +219,7 @@ export { default as HdsTextBody } from './components/hds/text/body.js';
219
219
  export { default as HdsTextCode } from './components/hds/text/code.js';
220
220
  export { default as HdsTextDisplay } from './components/hds/text/display.js';
221
221
  export { HdsTextAlignValues, HdsTextColorValues, HdsTextGroupValues, HdsTextSizeValues, HdsTextWeightValues } from './components/hds/text/types.js';
222
+ export { default as HdsThemeSwitcher } from './components/hds/theme-switcher/index.js';
222
223
  export { default as HdsTime } from './components/hds/time/index.js';
223
224
  export { default as HdsTimeSingle } from './components/hds/time/single.js';
224
225
  export { default as HdsTimeRange } from './components/hds/time/range.js';
@@ -1 +1 @@
1
- {"version":3,"file":"components.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"components.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,217 @@
1
+ import Service from '@ember/service';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { g, i } from 'decorator-transforms/runtime';
4
+
5
+ let HdsThemeValues = /*#__PURE__*/function (HdsThemeValues) {
6
+ // default (original HDS)
7
+ HdsThemeValues["Default"] = "default";
8
+ // system settings (prefers-color-scheme)
9
+ HdsThemeValues["System"] = "system";
10
+ // user settings for dark/light
11
+ HdsThemeValues["Light"] = "light";
12
+ HdsThemeValues["Dark"] = "dark";
13
+ return HdsThemeValues;
14
+ }({});
15
+
16
+ // TODO! understand if we really need this
17
+ var HdsModesBaseValues = /*#__PURE__*/function (HdsModesBaseValues) {
18
+ HdsModesBaseValues["Default"] = "default";
19
+ return HdsModesBaseValues;
20
+ }(HdsModesBaseValues || {});
21
+ var HdsModesLightValues = /*#__PURE__*/function (HdsModesLightValues) {
22
+ HdsModesLightValues["CdsG0"] = "cds-g0";
23
+ HdsModesLightValues["CdsG10"] = "cds-g10";
24
+ return HdsModesLightValues;
25
+ }(HdsModesLightValues || {});
26
+ var HdsModesDarkValues = /*#__PURE__*/function (HdsModesDarkValues) {
27
+ HdsModesDarkValues["CdsG90"] = "cds-g90";
28
+ HdsModesDarkValues["CdsG100"] = "cds-g100";
29
+ return HdsModesDarkValues;
30
+ }(HdsModesDarkValues || {});
31
+ let HdsCssSelectorsValues = /*#__PURE__*/function (HdsCssSelectorsValues) {
32
+ HdsCssSelectorsValues["Data"] = "data";
33
+ HdsCssSelectorsValues["Class"] = "class";
34
+ return HdsCssSelectorsValues;
35
+ }({});
36
+ const THEMES = Object.values(HdsThemeValues);
37
+ const MODES_LIGHT = Object.values(HdsModesLightValues);
38
+ const MODES_DARK = Object.values(HdsModesDarkValues);
39
+ const MODES = [...Object.values(HdsModesBaseValues), ...MODES_LIGHT, ...MODES_DARK];
40
+ const HDS_THEMING_DATA_SELECTOR = 'data-hds-theme';
41
+ const HDS_THEMING_CLASS_SELECTOR_PREFIX = 'hds-theme';
42
+ const HDS_THEMING_LOCALSTORAGE_DATA = 'hds-theming-data';
43
+ const DEFAULT_THEMING_OPTION_LIGHT_THEME = HdsModesLightValues.CdsG0;
44
+ const DEFAULT_THEMING_OPTION_DARK_THEME = HdsModesDarkValues.CdsG100;
45
+ const DEFAULT_THEMING_OPTION_CSS_SELECTOR = 'data';
46
+ class HdsThemingService extends Service {
47
+ static {
48
+ g(this.prototype, "_currentTheme", [tracked], function () {
49
+ return undefined;
50
+ });
51
+ }
52
+ #_currentTheme = (i(this, "_currentTheme"), void 0);
53
+ static {
54
+ g(this.prototype, "_currentMode", [tracked], function () {
55
+ return undefined;
56
+ });
57
+ }
58
+ #_currentMode = (i(this, "_currentMode"), void 0);
59
+ static {
60
+ g(this.prototype, "_currentLightTheme", [tracked], function () {
61
+ return DEFAULT_THEMING_OPTION_LIGHT_THEME;
62
+ });
63
+ }
64
+ #_currentLightTheme = (i(this, "_currentLightTheme"), void 0);
65
+ static {
66
+ g(this.prototype, "_currentDarkTheme", [tracked], function () {
67
+ return DEFAULT_THEMING_OPTION_DARK_THEME;
68
+ });
69
+ }
70
+ #_currentDarkTheme = (i(this, "_currentDarkTheme"), void 0);
71
+ static {
72
+ g(this.prototype, "_currentCssSelector", [tracked], function () {
73
+ return DEFAULT_THEMING_OPTION_CSS_SELECTOR;
74
+ });
75
+ }
76
+ #_currentCssSelector = (i(this, "_currentCssSelector"), void 0);
77
+ static {
78
+ g(this.prototype, "globalOnSetTheme", [tracked]);
79
+ }
80
+ #globalOnSetTheme = (i(this, "globalOnSetTheme"), void 0);
81
+ initializeTheme() {
82
+ const rawStoredThemingData = localStorage.getItem(HDS_THEMING_LOCALSTORAGE_DATA);
83
+ if (rawStoredThemingData !== null) {
84
+ const storedThemingData = JSON.parse(rawStoredThemingData);
85
+ if (storedThemingData) {
86
+ const {
87
+ theme,
88
+ options
89
+ } = storedThemingData;
90
+ this.setTheme({
91
+ theme,
92
+ options
93
+ });
94
+ }
95
+ }
96
+ }
97
+ setTheme({
98
+ theme,
99
+ options,
100
+ onSetTheme
101
+ }) {
102
+ if (options !== undefined) {
103
+ // if we have new options, we override the current ones (`lightTheme` / `darkTheme` / `cssSelector`)
104
+ // these options can be used by consumers that want to customize how they apply theming
105
+ // (and used by the showcase for the custom theming / theme switching logic)
106
+ if (Object.hasOwn(options, 'lightTheme') && Object.hasOwn(options, 'darkTheme') && Object.hasOwn(options, 'cssSelector')) {
107
+ const {
108
+ lightTheme,
109
+ darkTheme,
110
+ cssSelector
111
+ } = options;
112
+ this._currentLightTheme = lightTheme;
113
+ this._currentDarkTheme = darkTheme;
114
+ this._currentCssSelector = cssSelector;
115
+ } else {
116
+ // fallback if something goes wrong
117
+ this._currentLightTheme = DEFAULT_THEMING_OPTION_LIGHT_THEME;
118
+ this._currentDarkTheme = DEFAULT_THEMING_OPTION_DARK_THEME;
119
+ this._currentCssSelector = DEFAULT_THEMING_OPTION_CSS_SELECTOR;
120
+ }
121
+ }
122
+
123
+ // set the current theme/mode (`currentTheme` / `currentMode`)
124
+ let cssSelectorPartial;
125
+ if (theme === undefined ||
126
+ // standard (no theming)
127
+ !THEMES.includes(theme) // handle possible errors
128
+ ) {
129
+ this._currentTheme = undefined;
130
+ this._currentMode = undefined;
131
+ cssSelectorPartial = undefined;
132
+ } else if (theme === HdsThemeValues.Default // default (original HDS)
133
+ ) {
134
+ this._currentTheme = HdsThemeValues.Default;
135
+ this._currentMode = undefined;
136
+ cssSelectorPartial = HdsThemeValues.Default;
137
+ } else if (theme === HdsThemeValues.System // system (prefers-color-scheme)
138
+ ) {
139
+ this._currentTheme = HdsThemeValues.System;
140
+ this._currentMode = undefined;
141
+ cssSelectorPartial = HdsThemeValues.System;
142
+ } else {
143
+ this._currentTheme = theme;
144
+ if (this._currentTheme === HdsThemeValues.Light) {
145
+ this._currentMode = this._currentLightTheme;
146
+ }
147
+ if (this._currentTheme === HdsThemeValues.Dark) {
148
+ this._currentMode = this._currentDarkTheme;
149
+ }
150
+ cssSelectorPartial = options?.isComplex ? this._currentMode : this._currentTheme;
151
+ }
152
+
153
+ // IMPORTANT: for this to work, it needs to be the HTML tag (it's the `:root` in CSS)
154
+ const rootElement = document.querySelector('html');
155
+ if (!rootElement) {
156
+ return;
157
+ }
158
+ // remove or update the CSS selectors applied to the root element (depending on the `theme` argument)
159
+ rootElement.removeAttribute(HDS_THEMING_DATA_SELECTOR);
160
+ const hdsThemingClassesToRemove = Array.from(rootElement.classList).filter(className => className.startsWith(`${HDS_THEMING_CLASS_SELECTOR_PREFIX}-`));
161
+ rootElement.classList.remove(...hdsThemingClassesToRemove);
162
+ if (cssSelectorPartial !== undefined) {
163
+ if (this._currentCssSelector === 'data') {
164
+ rootElement.setAttribute(HDS_THEMING_DATA_SELECTOR, cssSelectorPartial);
165
+ } else if (this._currentCssSelector === 'class') {
166
+ rootElement.classList.add(`${HDS_THEMING_CLASS_SELECTOR_PREFIX}-${cssSelectorPartial}`);
167
+ }
168
+ }
169
+
170
+ // store the current theme and theming options in local storage (unless undefined)
171
+ localStorage.setItem(HDS_THEMING_LOCALSTORAGE_DATA, JSON.stringify({
172
+ theme: this._currentTheme,
173
+ options: {
174
+ lightTheme: this._currentLightTheme,
175
+ darkTheme: this._currentDarkTheme,
176
+ cssSelector: this._currentCssSelector
177
+ }
178
+ }));
179
+
180
+ // this is a general callback that can be defined globally (by extending the service)
181
+ if (this.globalOnSetTheme) {
182
+ this.globalOnSetTheme({
183
+ currentTheme: this._currentTheme,
184
+ currentMode: this._currentMode
185
+ });
186
+ }
187
+
188
+ // this is a "local" callback that can be defined "locally" (eg. in a theme switcher)
189
+ if (onSetTheme) {
190
+ onSetTheme({
191
+ currentTheme: this._currentTheme,
192
+ currentMode: this._currentMode
193
+ });
194
+ }
195
+ }
196
+
197
+ // getters used for reactivity in the components/services using this service
198
+
199
+ get currentTheme() {
200
+ return this._currentTheme;
201
+ }
202
+ get currentMode() {
203
+ return this._currentMode;
204
+ }
205
+ get currentLightTheme() {
206
+ return this._currentLightTheme ?? DEFAULT_THEMING_OPTION_LIGHT_THEME;
207
+ }
208
+ get currentDarkTheme() {
209
+ return this._currentDarkTheme ?? DEFAULT_THEMING_OPTION_DARK_THEME;
210
+ }
211
+ get currentCssSelector() {
212
+ return this._currentCssSelector ?? DEFAULT_THEMING_OPTION_CSS_SELECTOR;
213
+ }
214
+ }
215
+
216
+ export { DEFAULT_THEMING_OPTION_CSS_SELECTOR, DEFAULT_THEMING_OPTION_DARK_THEME, DEFAULT_THEMING_OPTION_LIGHT_THEME, HDS_THEMING_CLASS_SELECTOR_PREFIX, HDS_THEMING_DATA_SELECTOR, HDS_THEMING_LOCALSTORAGE_DATA, HdsCssSelectorsValues, HdsThemeValues, MODES, MODES_DARK, MODES_LIGHT, THEMES, HdsThemingService as default };
217
+ //# sourceMappingURL=hds-theming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hds-theming.js","sources":["../../src/services/hds-theming.ts"],"sourcesContent":["import Service from '@ember/service';\nimport { tracked } from '@glimmer/tracking';\n\nexport enum HdsThemeValues {\n // default (original HDS)\n Default = 'default',\n // system settings (prefers-color-scheme)\n System = 'system',\n // user settings for dark/light\n Light = 'light',\n Dark = 'dark',\n}\n\n// TODO! understand if we really need this\nenum HdsModesBaseValues {\n Default = 'default',\n}\n\nenum HdsModesLightValues {\n CdsG0 = 'cds-g0',\n CdsG10 = 'cds-g10',\n}\n\nenum HdsModesDarkValues {\n CdsG90 = 'cds-g90',\n CdsG100 = 'cds-g100',\n}\n\nexport enum HdsCssSelectorsValues {\n Data = 'data',\n Class = 'class',\n}\n\nexport type HdsThemes = `${HdsThemeValues}`;\nexport type HdsModes =\n | `${HdsModesBaseValues}`\n | `${HdsModesLightValues}`\n | `${HdsModesDarkValues}`;\nexport type HdsModesLight = `${HdsModesLightValues}`;\nexport type HdsModesDark = `${HdsModesDarkValues}`;\nexport type HdsCssSelectors = `${HdsCssSelectorsValues}`;\n\ntype HdsThemingOptions = {\n lightTheme: HdsModesLight;\n darkTheme: HdsModesDark;\n cssSelector: HdsCssSelectors;\n isComplex: boolean;\n};\n\ntype SetThemeArgs = {\n theme: HdsThemes | undefined;\n options?: HdsThemingOptions;\n onSetTheme?: OnSetThemeCallback;\n};\n\nexport type OnSetThemeCallbackArgs = {\n currentTheme: HdsThemes | undefined;\n currentMode: HdsModes | undefined;\n};\n\nexport type OnSetThemeCallback = (args: OnSetThemeCallbackArgs) => void;\n\nexport const THEMES: HdsThemes[] = Object.values(HdsThemeValues);\nexport const MODES_LIGHT: HdsModesLight[] = Object.values(HdsModesLightValues);\nexport const MODES_DARK: HdsModesDark[] = Object.values(HdsModesDarkValues);\nexport const MODES: HdsModes[] = [\n ...Object.values(HdsModesBaseValues),\n ...MODES_LIGHT,\n ...MODES_DARK,\n];\n\nexport const HDS_THEMING_DATA_SELECTOR = 'data-hds-theme';\nexport const HDS_THEMING_CLASS_SELECTOR_PREFIX = 'hds-theme';\n\nexport const HDS_THEMING_LOCALSTORAGE_DATA = 'hds-theming-data';\n\nexport const DEFAULT_THEMING_OPTION_LIGHT_THEME = HdsModesLightValues.CdsG0;\nexport const DEFAULT_THEMING_OPTION_DARK_THEME = HdsModesDarkValues.CdsG100;\nexport const DEFAULT_THEMING_OPTION_CSS_SELECTOR = 'data';\n\nexport default class HdsThemingService extends Service {\n @tracked _currentTheme: HdsThemes | undefined = undefined;\n @tracked _currentMode: HdsModes | undefined = undefined;\n @tracked _currentLightTheme: HdsModesLight =\n DEFAULT_THEMING_OPTION_LIGHT_THEME;\n @tracked _currentDarkTheme: HdsModesDark = DEFAULT_THEMING_OPTION_DARK_THEME;\n @tracked _currentCssSelector: HdsCssSelectors =\n DEFAULT_THEMING_OPTION_CSS_SELECTOR;\n @tracked globalOnSetTheme: OnSetThemeCallback | undefined;\n\n initializeTheme() {\n const rawStoredThemingData = localStorage.getItem(\n HDS_THEMING_LOCALSTORAGE_DATA\n );\n if (rawStoredThemingData !== null) {\n const storedThemingData: unknown = JSON.parse(rawStoredThemingData);\n if (storedThemingData) {\n const { theme, options } = storedThemingData as {\n theme: HdsThemes | undefined;\n options: HdsThemingOptions;\n };\n this.setTheme({\n theme,\n options,\n });\n }\n }\n }\n\n setTheme({ theme, options, onSetTheme }: SetThemeArgs) {\n if (options !== undefined) {\n // if we have new options, we override the current ones (`lightTheme` / `darkTheme` / `cssSelector`)\n // these options can be used by consumers that want to customize how they apply theming\n // (and used by the showcase for the custom theming / theme switching logic)\n if (\n Object.hasOwn(options, 'lightTheme') &&\n Object.hasOwn(options, 'darkTheme') &&\n Object.hasOwn(options, 'cssSelector')\n ) {\n const { lightTheme, darkTheme, cssSelector } = options;\n\n this._currentLightTheme = lightTheme;\n this._currentDarkTheme = darkTheme;\n this._currentCssSelector = cssSelector;\n } else {\n // fallback if something goes wrong\n this._currentLightTheme = DEFAULT_THEMING_OPTION_LIGHT_THEME;\n this._currentDarkTheme = DEFAULT_THEMING_OPTION_DARK_THEME;\n this._currentCssSelector = DEFAULT_THEMING_OPTION_CSS_SELECTOR;\n }\n }\n\n // set the current theme/mode (`currentTheme` / `currentMode`)\n let cssSelectorPartial;\n if (\n theme === undefined || // standard (no theming)\n !THEMES.includes(theme) // handle possible errors\n ) {\n this._currentTheme = undefined;\n this._currentMode = undefined;\n cssSelectorPartial = undefined;\n } else if (\n theme === HdsThemeValues.Default // default (original HDS)\n ) {\n this._currentTheme = HdsThemeValues.Default;\n this._currentMode = undefined;\n cssSelectorPartial = HdsThemeValues.Default;\n } else if (\n theme === HdsThemeValues.System // system (prefers-color-scheme)\n ) {\n this._currentTheme = HdsThemeValues.System;\n this._currentMode = undefined;\n cssSelectorPartial = HdsThemeValues.System;\n } else {\n this._currentTheme = theme;\n if (this._currentTheme === HdsThemeValues.Light) {\n this._currentMode = this._currentLightTheme;\n }\n if (this._currentTheme === HdsThemeValues.Dark) {\n this._currentMode = this._currentDarkTheme;\n }\n cssSelectorPartial = options?.isComplex\n ? this._currentMode\n : this._currentTheme;\n }\n\n // IMPORTANT: for this to work, it needs to be the HTML tag (it's the `:root` in CSS)\n const rootElement = document.querySelector('html');\n\n if (!rootElement) {\n return;\n }\n // remove or update the CSS selectors applied to the root element (depending on the `theme` argument)\n rootElement.removeAttribute(HDS_THEMING_DATA_SELECTOR);\n const hdsThemingClassesToRemove = Array.from(rootElement.classList).filter(\n (className) =>\n className.startsWith(`${HDS_THEMING_CLASS_SELECTOR_PREFIX}-`)\n );\n rootElement.classList.remove(...hdsThemingClassesToRemove);\n if (cssSelectorPartial !== undefined) {\n if (this._currentCssSelector === 'data') {\n rootElement.setAttribute(HDS_THEMING_DATA_SELECTOR, cssSelectorPartial);\n } else if (this._currentCssSelector === 'class') {\n rootElement.classList.add(\n `${HDS_THEMING_CLASS_SELECTOR_PREFIX}-${cssSelectorPartial}`\n );\n }\n }\n\n // store the current theme and theming options in local storage (unless undefined)\n localStorage.setItem(\n HDS_THEMING_LOCALSTORAGE_DATA,\n JSON.stringify({\n theme: this._currentTheme,\n options: {\n lightTheme: this._currentLightTheme,\n darkTheme: this._currentDarkTheme,\n cssSelector: this._currentCssSelector,\n },\n })\n );\n\n // this is a general callback that can be defined globally (by extending the service)\n if (this.globalOnSetTheme) {\n this.globalOnSetTheme({\n currentTheme: this._currentTheme,\n currentMode: this._currentMode,\n });\n }\n\n // this is a \"local\" callback that can be defined \"locally\" (eg. in a theme switcher)\n if (onSetTheme) {\n onSetTheme({\n currentTheme: this._currentTheme,\n currentMode: this._currentMode,\n });\n }\n }\n\n // getters used for reactivity in the components/services using this service\n\n get currentTheme(): HdsThemes | undefined {\n return this._currentTheme;\n }\n\n get currentMode(): HdsModes | undefined {\n return this._currentMode;\n }\n\n get currentLightTheme(): HdsModesLight {\n return this._currentLightTheme ?? DEFAULT_THEMING_OPTION_LIGHT_THEME;\n }\n\n get currentDarkTheme(): HdsModesDark {\n return this._currentDarkTheme ?? DEFAULT_THEMING_OPTION_DARK_THEME;\n }\n\n get currentCssSelector(): HdsCssSelectors {\n return this._currentCssSelector ?? DEFAULT_THEMING_OPTION_CSS_SELECTOR;\n }\n}\n"],"names":["HdsThemeValues","HdsModesBaseValues","HdsModesLightValues","HdsModesDarkValues","HdsCssSelectorsValues","THEMES","Object","values","MODES_LIGHT","MODES_DARK","MODES","HDS_THEMING_DATA_SELECTOR","HDS_THEMING_CLASS_SELECTOR_PREFIX","HDS_THEMING_LOCALSTORAGE_DATA","DEFAULT_THEMING_OPTION_LIGHT_THEME","CdsG0","DEFAULT_THEMING_OPTION_DARK_THEME","CdsG100","DEFAULT_THEMING_OPTION_CSS_SELECTOR","HdsThemingService","Service","g","prototype","tracked","undefined","i","void 0","initializeTheme","rawStoredThemingData","localStorage","getItem","storedThemingData","JSON","parse","theme","options","setTheme","onSetTheme","hasOwn","lightTheme","darkTheme","cssSelector","_currentLightTheme","_currentDarkTheme","_currentCssSelector","cssSelectorPartial","includes","_currentTheme","_currentMode","Default","System","Light","Dark","isComplex","rootElement","document","querySelector","removeAttribute","hdsThemingClassesToRemove","Array","from","classList","filter","className","startsWith","remove","setAttribute","add","setItem","stringify","globalOnSetTheme","currentTheme","currentMode","currentLightTheme","currentDarkTheme","currentCssSelector"],"mappings":"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"}
package/dist/services.js CHANGED
@@ -1,2 +1,2 @@
1
-
1
+ export { DEFAULT_THEMING_OPTION_CSS_SELECTOR, DEFAULT_THEMING_OPTION_DARK_THEME, DEFAULT_THEMING_OPTION_LIGHT_THEME, HDS_THEMING_CLASS_SELECTOR_PREFIX, HDS_THEMING_DATA_SELECTOR, HDS_THEMING_LOCALSTORAGE_DATA, HdsCssSelectorsValues, HdsThemeValues, MODES, MODES_DARK, MODES_LIGHT, THEMES } from './services/hds-theming.js';
2
2
  //# sourceMappingURL=services.js.map