@pure-ds/storybook 0.7.25 → 0.7.26

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 (68) hide show
  1. package/.storybook/preview.js +5 -4
  2. package/dist/pds-reference.json +2266 -1017
  3. package/package.json +2 -2
  4. package/public/assets/js/app.js +1 -1
  5. package/public/assets/js/pds-ask.js +6 -6
  6. package/public/assets/js/pds-manager.js +104 -29
  7. package/public/assets/pds/components/pds-calendar.js +91 -159
  8. package/public/assets/pds/components/pds-daterange.js +683 -0
  9. package/public/assets/pds/components/pds-form.js +123 -21
  10. package/public/assets/pds/components/pds-rating.js +648 -0
  11. package/public/assets/pds/components/pds-tags.js +802 -0
  12. package/public/assets/pds/core/pds-ask.js +6 -6
  13. package/public/assets/pds/core/pds-manager.js +104 -29
  14. package/public/assets/pds/custom-elements.json +1099 -74
  15. package/public/assets/pds/pds-css-complete.json +7 -2
  16. package/public/assets/pds/pds-runtime-config.json +1 -1
  17. package/public/assets/pds/pds.css-data.json +4 -4
  18. package/public/assets/pds/styles/pds-components.css +96 -24
  19. package/public/assets/pds/styles/pds-components.css.js +192 -48
  20. package/public/assets/pds/styles/pds-primitives.css +6 -3
  21. package/public/assets/pds/styles/pds-primitives.css.js +12 -6
  22. package/public/assets/pds/styles/pds-styles.css +104 -29
  23. package/public/assets/pds/styles/pds-styles.css.js +208 -58
  24. package/public/assets/pds/styles/pds-utilities.css +2 -2
  25. package/public/assets/pds/styles/pds-utilities.css.js +4 -4
  26. package/public/assets/pds/vscode-custom-data.json +97 -0
  27. package/src/js/common/ask.js +122 -12
  28. package/src/js/pds-core/pds-generator.js +103 -28
  29. package/src/js/pds-core/pds-ontology.js +2 -2
  30. package/stories/components/PdsCalendar.stories.js +650 -168
  31. package/stories/components/PdsDaterange.stories.js +85 -0
  32. package/stories/components/PdsForm.Basics.stories.js +16 -0
  33. package/stories/components/PdsForm.ConditionalAndCalculated.stories.js +16 -0
  34. package/stories/components/PdsForm.CustomContent.stories.js +10 -0
  35. package/stories/components/PdsForm.Dialogs.stories.js +7 -0
  36. package/stories/components/PdsForm.Layout.stories.js +16 -0
  37. package/stories/components/PdsForm.SelectionAndArrays.stories.js +12 -0
  38. package/stories/components/PdsForm.stories.js +179 -219
  39. package/stories/components/PdsIcon.stories.js +17 -7
  40. package/stories/components/PdsOmnibox.stories.js +1 -60
  41. package/stories/components/PdsRating.stories.js +126 -0
  42. package/stories/components/PdsTags.stories.js +224 -0
  43. package/stories/components/PdsToaster.stories.js +1 -1
  44. package/stories/components/omnibox-countries-api-settings.js +63 -0
  45. package/stories/foundations/Colors.stories.js +6 -1
  46. package/stories/foundations/HTMLDefaults.stories.js +6 -6
  47. package/stories/foundations/Icons.stories.js +4 -4
  48. package/stories/foundations/MeshGradients.stories.js +13 -3
  49. package/stories/foundations/SmartSurfaces.stories.js +43 -31
  50. package/stories/foundations/Typography.stories.js +30 -108
  51. package/stories/foundations/ZIndex.stories.js +3 -3
  52. package/stories/layout/LayoutOverview.stories.js +3 -3
  53. package/stories/layout/LayoutSystem.stories.js +24 -18
  54. package/stories/patterns/BorderEffects.stories.js +28 -16
  55. package/stories/patterns/InteractiveStates.stories.js +39 -24
  56. package/stories/patterns/Utilities.stories.js +45 -23
  57. package/stories/primitives/ArticleLayout.stories.js +176 -0
  58. package/stories/primitives/Badges.stories.js +24 -8
  59. package/stories/primitives/Buttons.stories.js +29 -9
  60. package/stories/primitives/Callouts.stories.js +8 -7
  61. package/stories/primitives/Cards.stories.js +4 -1
  62. package/stories/primitives/FormElements.stories.js +8 -2
  63. package/stories/primitives/HtmlFormElements.stories.js +8 -2
  64. package/stories/primitives/HtmlFormGroups.stories.js +5 -2
  65. package/stories/primitives/Media.stories.js +44 -30
  66. package/stories/primitives/Tables.stories.js +25 -7
  67. package/stories/utils/PdsAsk.stories.js +17 -5
  68. package/stories/utils/PdsObjectApi.stories.js +16 -4
@@ -1,6 +1,7 @@
1
1
  import { html, nothing } from "#pds/lit";
2
2
  import { createComponentDocsPage } from "../reference/reference-docs.js";
3
3
  import showdown from "showdown";
4
+ import { countriesApiSettings } from "./omnibox-countries-api-settings.js";
4
5
 
5
6
  const markdownConverter = new showdown.Converter({
6
7
  tables: true,
@@ -275,8 +276,10 @@ Override the automatically selected widget for a field.
275
276
  | \`input-email\` | String | Email with validation |
276
277
  | \`input-url\` | String | URL with validation |
277
278
  | \`input-number\` | Number | Default for numbers |
279
+ | \`pds-rating\` (or \`rating\`) | Number | Star rating input (pds-rating) |
278
280
  | \`input-range\` | Number | Slider control |
279
281
  | \`input-date\` | String | Date picker |
282
+ | \`input-iso-interval\` | String | Date range picker (pds-daterange) |
280
283
  | \`input-time\` | String | Time picker |
281
284
  | \`input-datetime\` | String | Date + time picker |
282
285
  | \`input-color\` | String | Color picker |
@@ -664,6 +667,7 @@ See the examples below to get started, or check the [primitive forms](/story/pri
664
667
 
665
668
  export default {
666
669
  title: "Components/pds-form",
670
+ includeStories: [],
667
671
  tags: ["autodocs", "forms", "json-schema", "validation", "input"],
668
672
  parameters: {
669
673
  pds: {
@@ -680,30 +684,6 @@ export default {
680
684
  },
681
685
  };
682
686
 
683
- const buildSimpleOmniboxSettings = () => ({
684
- hideCategory: true,
685
- itemGrid: "0 1fr 0",
686
- iconHandler: () => '',
687
- categories: {
688
- Suggestions: {
689
- trigger: () => true,
690
- getItems: async (options) => {
691
- const q = (options.search || "").toLowerCase();
692
- const items = {
693
- netherlands: "Netherlands",
694
- unitedStates: "United States",
695
- japan: "Japan",
696
- germany: "Germany",
697
- };
698
-
699
- return Object.entries(items)
700
- .filter(([key, label]) => `${key} ${label}`.toLowerCase().includes(q))
701
- .map(([key, label]) => ({ id: key, text: label }));
702
- },
703
- },
704
- },
705
- });
706
-
707
687
  const simpleSchema = {
708
688
  type: "object",
709
689
  properties: {
@@ -831,14 +811,6 @@ const complexUiSchema = {
831
811
  "ui:icon": "calendar",
832
812
  "ui:iconPosition": "start",
833
813
  },
834
- "/address/street": {
835
- "ui:icon": "map-pin",
836
- "ui:iconPosition": "start",
837
- },
838
- "/address/city": {
839
- "ui:icon": "building",
840
- "ui:iconPosition": "start",
841
- },
842
814
  "address/country": {
843
815
  "ui:class": "buttons"
844
816
  },
@@ -1257,7 +1229,7 @@ export const WithPdsOmnibox = {
1257
1229
  "ui:icon": "globe",
1258
1230
  "ui:options": {
1259
1231
  icon: "globe",
1260
- settings: buildSimpleOmniboxSettings(),
1232
+ settings: countriesApiSettings,
1261
1233
  },
1262
1234
  },
1263
1235
  };
@@ -1693,6 +1665,7 @@ export const WithTabsLayout = {
1693
1665
  examples: ["••••••••"],
1694
1666
  },
1695
1667
  },
1668
+ required: ["username", "email", "password"],
1696
1669
  },
1697
1670
  profile: {
1698
1671
  type: "object",
@@ -1731,7 +1704,8 @@ export const WithTabsLayout = {
1731
1704
  searchable: { type: "boolean", title: "Searchable" },
1732
1705
  },
1733
1706
  },
1734
- },
1707
+ }
1708
+
1735
1709
  },
1736
1710
  },
1737
1711
  };
@@ -1937,83 +1911,89 @@ export const WithDialogForms = {
1937
1911
  title: "Project Name",
1938
1912
  examples: ["Digital Transformation Initiative"],
1939
1913
  },
1940
- teamLead: {
1914
+ elements: {
1941
1915
  type: "object",
1942
- title: "Team Lead",
1916
+ title: "Elements",
1943
1917
  properties: {
1944
- name: {
1945
- type: "string",
1946
- title: "Full Name",
1947
- examples: ["Sarah Johnson"],
1948
- },
1949
- email: {
1950
- type: "string",
1951
- format: "email",
1952
- title: "Email Address",
1953
- examples: ["sarah.johnson@company.com"],
1954
- },
1955
- phone: {
1956
- type: "string",
1957
- title: "Phone Number",
1958
- examples: ["+1-555-0123"],
1959
- },
1960
- department: {
1961
- type: "string",
1962
- title: "Department",
1963
- examples: ["Engineering"],
1964
- },
1965
- location: {
1966
- type: "string",
1967
- title: "Office Location",
1968
- examples: ["New York Office"],
1969
- },
1970
- },
1971
- },
1972
- budget: {
1973
- type: "object",
1974
- title: "Budget Details",
1975
- properties: {
1976
- amount: {
1977
- type: "number",
1978
- title: "Budget Amount",
1979
- examples: [250000],
1980
- },
1981
- currency: {
1982
- type: "string",
1983
- title: "Currency",
1984
- enum: ["USD", "EUR", "GBP", "JPY", "AUD"],
1985
- },
1986
- fiscalYear: {
1987
- type: "string",
1988
- title: "Fiscal Year",
1989
- examples: ["2025"],
1990
- },
1991
- department: {
1992
- type: "string",
1993
- title: "Cost Center",
1994
- examples: ["IT-001"],
1918
+ teamlead: {
1919
+ type: "object",
1920
+ title: "Team Lead",
1921
+ properties: {
1922
+ name: {
1923
+ type: "string",
1924
+ title: "Full Name",
1925
+ examples: ["Sarah Johnson"],
1926
+ },
1927
+ email: {
1928
+ type: "string",
1929
+ format: "email",
1930
+ title: "Email Address",
1931
+ examples: ["sarah.johnson@company.com"],
1932
+ },
1933
+ phone: {
1934
+ type: "string",
1935
+ title: "Phone Number",
1936
+ examples: ["+1-555-0123"],
1937
+ },
1938
+ department: {
1939
+ type: "string",
1940
+ title: "Department",
1941
+ examples: ["Engineering"],
1942
+ },
1943
+ location: {
1944
+ type: "string",
1945
+ title: "Office Location",
1946
+ examples: ["New York Office"],
1947
+ },
1948
+ },
1995
1949
  },
1996
- approved: { type: "boolean", title: "Budget Approved" },
1997
- },
1998
- },
1999
- timeline: {
2000
- type: "object",
2001
- title: "Project Timeline",
2002
- properties: {
2003
- startDate: { type: "string", format: "date", title: "Start Date" },
2004
- endDate: { type: "string", format: "date", title: "End Date" },
2005
- milestones: {
2006
- type: "integer",
2007
- title: "Number of Milestones",
2008
- minimum: 1,
2009
- maximum: 20,
2010
- examples: [8],
1950
+ budget: {
1951
+ type: "object",
1952
+ title: "Budget Details",
1953
+ properties: {
1954
+ amount: {
1955
+ type: "number",
1956
+ title: "Budget Amount",
1957
+ examples: [250000],
1958
+ },
1959
+ currency: {
1960
+ type: "string",
1961
+ title: "Currency",
1962
+ enum: ["USD", "EUR", "GBP", "JPY", "AUD"],
1963
+ },
1964
+ fiscalYear: {
1965
+ type: "string",
1966
+ title: "Fiscal Year",
1967
+ examples: ["2025"],
1968
+ },
1969
+ department: {
1970
+ type: "string",
1971
+ title: "Cost Center",
1972
+ examples: ["IT-001"],
1973
+ },
1974
+ approved: { type: "boolean", title: "Budget Approved" },
1975
+ },
2011
1976
  },
2012
- status: {
2013
- type: "string",
2014
- title: "Status",
2015
- enum: ["Planning", "In Progress", "On Hold", "Completed"],
2016
- default: "Planning",
1977
+ timeline: {
1978
+ type: "object",
1979
+ title: "Project Timeline",
1980
+ required: ["period"],
1981
+ properties: {
1982
+ period: { type: "string", format: "iso-interval", title: "Project Timeline" },
1983
+ milestones: {
1984
+ type: "integer",
1985
+ title: "Number of Milestones",
1986
+ minimum: 1,
1987
+ maximum: 20,
1988
+ examples: [8],
1989
+ },
1990
+ status: {
1991
+ type: "string",
1992
+ title: "Status",
1993
+ enum: ["Planning", "In Progress", "On Hold", "Completed"],
1994
+ default: "Planning",
1995
+ },
1996
+ },
2017
1997
  },
2018
1998
  },
2019
1999
  },
@@ -2023,25 +2003,26 @@ export const WithDialogForms = {
2023
2003
  // Initial values to test state persistence
2024
2004
  const initialValues = {
2025
2005
  projectName: "Digital Transformation Initiative",
2026
- teamLead: {
2027
- name: "Sarah Johnson",
2028
- email: "sarah.johnson@company.com",
2029
- phone: "+1-555-0123",
2030
- department: "Engineering",
2031
- location: "New York Office",
2032
- },
2033
- budget: {
2034
- amount: 250000,
2035
- currency: "USD",
2036
- fiscalYear: "2025",
2037
- department: "IT-001",
2038
- approved: true,
2039
- },
2040
- timeline: {
2041
- startDate: "2025-01-15",
2042
- endDate: "2025-12-31",
2043
- milestones: 8,
2044
- status: "In Progress",
2006
+ elements: {
2007
+ teamlead: {
2008
+ name: "Sarah Johnson",
2009
+ email: "sarah.johnson@company.com",
2010
+ phone: "+1-555-0123",
2011
+ department: "Engineering",
2012
+ location: "New York Office",
2013
+ },
2014
+ budget: {
2015
+ amount: 250000,
2016
+ currency: "USD",
2017
+ fiscalYear: "2025",
2018
+ department: "IT-001",
2019
+ approved: true,
2020
+ },
2021
+ timeline: {
2022
+ period: "2025-01-15/2025-12-31",
2023
+ milestones: 8,
2024
+ status: "In Progress",
2025
+ },
2045
2026
  },
2046
2027
  };
2047
2028
 
@@ -2050,61 +2031,68 @@ export const WithDialogForms = {
2050
2031
  "ui:icon": "folder",
2051
2032
  "ui:iconPosition": "start",
2052
2033
  },
2053
- teamLead: {
2054
- "ui:dialog": true,
2055
- "ui:dialogOptions": {
2056
- buttonLabel: "Edit Team Lead",
2057
- dialogTitle: "Team Lead Information",
2058
- icon: "user-gear",
2034
+ elements: {
2035
+ "ui:layout": "grid",
2036
+ "ui:layoutOptions": {
2037
+ columns: 3,
2038
+ gap: "md",
2059
2039
  },
2060
- name: { "ui:icon": "user", "ui:iconPosition": "start" },
2061
- email: { "ui:icon": "envelope", "ui:iconPosition": "start" },
2062
- phone: { "ui:icon": "phone", "ui:iconPosition": "start" },
2063
- department: { "ui:icon": "building", "ui:iconPosition": "start" },
2064
- location: { "ui:icon": "map-pin", "ui:iconPosition": "start" },
2065
- },
2066
- budget: {
2067
- "ui:dialog": true,
2068
- "ui:dialogOptions": {
2069
- buttonLabel: "Edit Budget",
2070
- dialogTitle: "Budget Details",
2071
- icon: "currency-dollar",
2040
+ teamlead: {
2041
+ "ui:dialog": true,
2042
+ "ui:dialogOptions": {
2043
+ buttonLabel: "Edit Team Lead",
2044
+ dialogTitle: "Team Lead Information",
2045
+ icon: "user-gear",
2046
+ },
2047
+ name: { "ui:icon": "user", "ui:iconPosition": "start" },
2048
+ email: { "ui:icon": "at", "ui:iconPosition": "start" },
2049
+ phone: { "ui:icon": "phone", "ui:iconPosition": "start" },
2050
+ department: { "ui:icon": "receipt", "ui:iconPosition": "start" },
2051
+ location: { "ui:icon": "map-pin", "ui:iconPosition": "start" },
2052
+ },
2053
+ budget: {
2054
+ "ui:dialog": true,
2055
+ "ui:dialogOptions": {
2056
+ buttonLabel: "Edit Budget",
2057
+ dialogTitle: "Budget Details",
2058
+ icon: "currency-dollar",
2059
+ },
2060
+ amount: { "ui:icon": "currency-dollar", "ui:iconPosition": "start" },
2061
+ currency: { "ui:icon": "coins", "ui:iconPosition": "start" },
2062
+ fiscalYear: { "ui:icon": "calendar", "ui:iconPosition": "start" },
2063
+ department: { "ui:icon": "receipt", "ui:iconPosition": "start" },
2064
+ },
2065
+ timeline: {
2066
+ "ui:dialog": true,
2067
+ "ui:dialogOptions": {
2068
+ buttonLabel: "Edit Timeline",
2069
+ dialogTitle: "Project Timeline",
2070
+ icon: "calendar",
2071
+ },
2072
+ period: {},
2073
+ milestones: { "ui:icon": "check", "ui:iconPosition": "start" },
2074
+ status: { "ui:icon": "list-check", "ui:iconPosition": "start" },
2072
2075
  },
2073
- amount: { "ui:icon": "dollar-sign", "ui:iconPosition": "start" },
2074
- currency: { "ui:icon": "coins", "ui:iconPosition": "start" },
2075
- fiscalYear: { "ui:icon": "calendar", "ui:iconPosition": "start" },
2076
- department: { "ui:icon": "building", "ui:iconPosition": "start" },
2077
2076
  },
2078
2077
  // Flat path for dialog inner form - currency field inside budget dialog
2079
2078
  "/currency": { "ui:widget": "select" },
2080
2079
  // Flat path for dialog inner form - status field inside timeline dialog
2081
2080
  "/status": { "ui:class": "buttons" },
2082
- // Flat path for dialog inner form - email field inside teamLead dialog
2081
+ // Flat path for dialog inner form - email field inside teamlead dialog
2083
2082
  "/email": { "ui:icon": "at", "ui:iconPosition": "start" },
2084
- // Flat path for dialog inner form - phone field inside teamLead dialog
2083
+ // Flat path for dialog inner form - phone field inside teamlead dialog
2085
2084
  "/phone": { "ui:icon": "phone", "ui:iconPosition": "start" },
2086
- timeline: {
2087
- "ui:dialog": true,
2088
- "ui:dialogOptions": {
2089
- buttonLabel: "Edit Timeline",
2090
- dialogTitle: "Project Timeline",
2091
- icon: "calendar",
2092
- },
2093
- startDate: { "ui:icon": "calendar-check", "ui:iconPosition": "start" },
2094
- endDate: { "ui:icon": "calendar-xmark", "ui:iconPosition": "start" },
2095
- milestones: { "ui:icon": "flag", "ui:iconPosition": "start" },
2096
- status: { "ui:icon": "list-check", "ui:iconPosition": "start" },
2097
- },
2098
2085
  };
2099
2086
 
2100
2087
  return html`
2101
- <pds-form
2102
- .jsonSchema=${schema}
2103
- .uiSchema=${uiSchema}
2104
- .values=${initialValues}
2105
- @pw:submit=${(e) => toastFormData(e.detail)}
2106
- @pw:dialog-submit=${(e) => console.log("📝 Dialog saved:", e.detail)}
2107
- ></pds-form>
2088
+ <div class="flex flex-col gap-md">
2089
+ <pds-form
2090
+ .jsonSchema=${schema}
2091
+ .uiSchema=${uiSchema}
2092
+ .values=${initialValues}
2093
+ @pw:submit=${(e) => toastFormData(e.detail)}
2094
+ ></pds-form>
2095
+ </div>
2108
2096
  `;
2109
2097
  },
2110
2098
  };
@@ -4792,55 +4780,22 @@ This is like using \`defineRenderer()\` but inline in the uiSchema.`,
4792
4780
  maximum: 5,
4793
4781
  default: 4,
4794
4782
  },
4795
- review: { type: "string", title: "Review" },
4783
+ review: { type: "string", title: "Review", examples: ["Great sound quality and battery life!"] },
4796
4784
  recommend: { type: "boolean", title: "Would recommend", default: true },
4797
4785
  },
4798
4786
  };
4799
4787
 
4800
4788
  const uiSchema = {
4801
- // Custom star rating widget
4789
+ // Built-in rating widget
4802
4790
  "/rating": {
4803
- "ui:render": (field) => {
4804
- const stars = [1, 2, 3, 4, 5];
4805
- return html`
4806
- <fieldset data-path=${field.path}>
4807
- <legend>${field.label}</legend>
4808
- <div
4809
- class="flex gap-xs"
4810
- role="radiogroup"
4811
- aria-label="${field.label}"
4812
- >
4813
- ${stars.map(
4814
- (star) => html`
4815
- <button
4816
- type="button"
4817
- class="btn btn-sm ${star <= (field.value || 0)
4818
- ? "btn-primary"
4819
- : "btn-outline"}"
4820
- @click=${() => field.set(star)}
4821
- aria-label="${star} star${star > 1 ? "s" : ""}"
4822
- aria-pressed=${star <= (field.value || 0)}
4823
- >
4824
-
4825
- </button>
4826
- `
4827
- )}
4828
- </div>
4829
- <input
4830
- type="hidden"
4831
- name=${field.path}
4832
- .value=${String(field.value || "")}
4833
- />
4834
- </fieldset>
4835
- `;
4836
- },
4791
+ "ui:widget": "rating",
4837
4792
  },
4838
4793
 
4839
4794
  // Custom toggle card for recommendation
4840
4795
  "/recommend": {
4841
4796
  "ui:render": (field) => html`
4842
4797
  <div
4843
- class="card surface-elevated p-md cursor-pointer flex items-center gap-md"
4798
+ class="flex items-center gap-sm"
4844
4799
  @click=${() => field.set(!field.value)}
4845
4800
  role="checkbox"
4846
4801
  aria-checked=${!!field.value}
@@ -4849,19 +4804,19 @@ This is like using \`defineRenderer()\` but inline in the uiSchema.`,
4849
4804
  e.key === " " && (e.preventDefault(), field.set(!field.value))}
4850
4805
  >
4851
4806
  <span
4852
- style="cursor: pointer; font-size: 3rem; color: var(--color-${field.value
4807
+ style="cursor: pointer; font-size: 2rem; color: var(--color-${field.value
4853
4808
  ? "success"
4854
- : "neutral"}-500)"
4809
+ : "gray"}-500)"
4855
4810
  >${field.value ? "👍" : "👎"}</span
4856
4811
  >
4857
- <div>
4858
- <strong>${field.label}</strong>
4859
- <p class="text-sm text-muted">
4860
- ${field.value
4812
+
4813
+ <h4>
4814
+ ${field.value
4861
4815
  ? "Yes, I would recommend this!"
4862
4816
  : "No, I would not recommend this"}
4863
- </p>
4864
- </div>
4817
+ </h4>
4818
+
4819
+
4865
4820
  <input
4866
4821
  type="hidden"
4867
4822
  name=${field.path}
@@ -4879,11 +4834,16 @@ This is like using \`defineRenderer()\` but inline in the uiSchema.`,
4879
4834
 
4880
4835
  return html`
4881
4836
  <div class="callout callout-info">
4882
- <p><strong>Custom rendered fields:</strong></p>
4883
- <ul>
4884
- <li><strong>Rating</strong> uses a custom star button widget</li>
4885
- <li><strong>Would recommend</strong> uses a custom toggle card</li>
4886
- </ul>
4837
+ <span class="callout-icon">
4838
+ <pds-icon icon="sparkle" size="md"></pds-icon>
4839
+ </span>
4840
+ <div>
4841
+ <strong class="callout-title">Custom rendered fields</strong>
4842
+ <ul>
4843
+ <li><strong>Rating</strong> uses built-in <code>ui:widget: "rating"</code></li>
4844
+ <li><strong>Would recommend</strong> uses a custom toggle card</li>
4845
+ </ul>
4846
+ </div>
4887
4847
  </div>
4888
4848
  <pds-form
4889
4849
  .jsonSchema=${schema}
@@ -83,13 +83,23 @@ export const Default = {
83
83
  },
84
84
  render: (args) => html`
85
85
  <div class="stack-lg">
86
- <a href="/?path=/story/foundations-icons--overview" @click=${storyLinkHandler('foundations-icons--overview')} class="card card-interactive">
87
- <h3 class="flex items-center gap-sm">
88
- <pds-icon icon="book-open" size="md"></pds-icon>
89
- PDS Icon System
90
- </h3>
91
- <p class="text-muted">Complete icon system documentation: available icons, sizes, colors, configuration, and more.</p>
92
- </a>
86
+ <div class="callout callout-info">
87
+ <span class="callout-icon">
88
+ <pds-icon icon="info" size="md"></pds-icon>
89
+ </span>
90
+ <div class="stack-xs">
91
+ <strong class="callout-title">
92
+ <a href="/?path=/story/foundations-icons" @click=${storyLinkHandler('foundations-icons--overview')}>
93
+ Icon System
94
+ </a>
95
+ </strong>
96
+ <div>
97
+ <a href="/?path=/story/foundations-icons" @click=${storyLinkHandler('foundations-icons--overview')}>
98
+ Complete icon system documentation: available icons, sizes, colors, configuration, and more.
99
+ </a>
100
+ </div>
101
+ </div>
102
+ </div>
93
103
 
94
104
  <pds-icon
95
105
  icon="${args.icon}"
@@ -1,5 +1,6 @@
1
1
  import { html, lazyProps } from "#pds/lit";
2
2
  import { PDS } from "#pds";
3
+ import { countriesApiSettings } from "./omnibox-countries-api-settings.js";
3
4
 
4
5
  const docsParameters = {
5
6
  description: {
@@ -181,30 +182,6 @@ const inFormSettingsSource = `const settings = {
181
182
  <button class="btn-primary" type="submit">Submit</button>
182
183
  </form>`;
183
184
 
184
- let countryListPromise;
185
- const loadCountries = async () => {
186
- if (!countryListPromise) {
187
- countryListPromise = fetch("https://restcountries.com/v3.1/all?fields=name,cca2")
188
- .then((res) => {
189
- if (!res.ok) {
190
- throw new Error(`Failed to fetch countries: ${res.status}`);
191
- }
192
- return res.json();
193
- })
194
- .then((rows) =>
195
- rows
196
- .map((row) => ({
197
- id: row?.cca2 || row?.name?.common || "",
198
- text: row?.name?.common || "",
199
- icon: "globe",
200
- }))
201
- .filter((row) => row.id && row.text)
202
- .sort((a, b) => a.text.localeCompare(b.text)),
203
- );
204
- }
205
- return countryListPromise;
206
- };
207
-
208
185
  const countriesApiSettingsSource = `const settings = {
209
186
  hideCategory: true,
210
187
  itemGrid: "0 1fr 0",
@@ -251,42 +228,6 @@ const countriesApiSettingsSource = `const settings = {
251
228
  <button class="btn-primary" type="submit">Submit</button>
252
229
  </form>`;
253
230
 
254
- const countriesApiSettings = {
255
- hideCategory: true,
256
- itemGrid: "0 1fr 0",
257
- iconHandler: () => '',
258
- categories: {
259
- Featured: {
260
- sortIndex: 2,
261
- trigger: () => true,
262
- getItems: async (options) => {
263
- const q = (options.search || "").trim().toLowerCase();
264
- const shortlist = [
265
- { id: "NL", text: "Netherlands" },
266
- { id: "US", text: "United States" },
267
- ];
268
- return q
269
- ? shortlist.filter((item) => item.text.toLowerCase().includes(q))
270
- : shortlist;
271
- },
272
- useIconForInput: false,
273
- },
274
- Countries: {
275
- sortIndex: 1,
276
- trigger: (options) => (options.search || "").trim().length >= 2,
277
- getItems: async (options) => {
278
- const q = (options.search || "").trim().toLowerCase();
279
- if (!q) return [];
280
- const countries = await loadCountries();
281
- return countries
282
- .filter((item) => item.text.toLowerCase().includes(q))
283
- .slice(0, 30);
284
- },
285
- useIconForInput: false,
286
- },
287
- },
288
- };
289
-
290
231
  const combinedSettingsSource = `const settings = {
291
232
  hideCategory: false,
292
233
  iconHandler: (item) =>