@pgcorp/ui-kit 0.7.3 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +161 -8
  2. package/docs/accessibility.md +12 -0
  3. package/docs/getting-started.md +32 -2
  4. package/docs/public-api.md +27 -2
  5. package/package.json +18 -3
  6. package/src/components/shared/codeLanguages.ts +2 -107
  7. package/src/components/shared/containers/SPanel.css +32 -1
  8. package/src/components/shared/containers/SPanel.vue +4 -0
  9. package/src/components/shared/controls/SCheckbox.vue +2 -2
  10. package/src/components/shared/controls/SInteractiveSurface.css +54 -4
  11. package/src/components/shared/controls/SInteractiveSurface.vue +45 -31
  12. package/src/components/shared/controls/SListbox.vue +4 -4
  13. package/src/components/shared/controls/SSwitch.vue +2 -2
  14. package/src/components/shared/data-display/SActionCard.css +6 -2
  15. package/src/components/shared/data-display/SActionCard.vue +13 -3
  16. package/src/components/shared/data-display/SActionListItem.css +7 -8
  17. package/src/components/shared/data-display/SActionListItem.vue +21 -18
  18. package/src/components/shared/data-display/SChart.css +149 -0
  19. package/src/components/shared/data-display/SChart.vue +493 -0
  20. package/src/components/shared/data-display/SChip.css +24 -0
  21. package/src/components/shared/data-display/SChip.vue +30 -6
  22. package/src/components/shared/data-display/SCodeBlock.css +68 -0
  23. package/src/components/shared/data-display/SCodeBlock.vue +102 -16
  24. package/src/components/shared/data-display/SMetricCard.css +1 -0
  25. package/src/components/shared/data-display/SMetricCard.vue +1 -0
  26. package/src/components/shared/data-display/STable.vue +120 -145
  27. package/src/components/shared/data-display/chart.ts +54 -0
  28. package/src/components/shared/navigation/STabList.vue +0 -3
  29. package/src/internal/chartGeometry.ts +852 -0
  30. package/src/internal/codeLanguageIdentity.ts +89 -0
  31. package/src/internal/lazyCodeEditor.ts +1 -0
  32. package/src/internal/linkTarget.ts +1 -3
  33. package/src/internal/ownedAttrs.ts +1 -0
  34. package/src/internal/useBinaryInput.ts +9 -2
  35. package/src/styles/tailwind.css +3 -0
  36. package/src/styles/tokens.css +33 -0
@@ -0,0 +1,89 @@
1
+ import {
2
+ type CodeEditorLanguageContract,
3
+ validateCodeEditorLanguage,
4
+ } from './codeEditorContract'
5
+
6
+ type NullableText = string | null | undefined
7
+
8
+ const SPECIAL_FILENAMES: Readonly<Record<string, string>> = {
9
+ 'cmakelists.txt': 'cmake',
10
+ 'dockerfile': 'dockerfile',
11
+ 'docker-compose.yml': 'yaml',
12
+ 'docker-compose.yaml': 'yaml',
13
+ 'compose.yml': 'yaml',
14
+ 'compose.yaml': 'yaml',
15
+ '.env': 'properties',
16
+ '.env.example': 'properties',
17
+ '.env.local': 'properties',
18
+ '.env.development': 'properties',
19
+ '.env.production': 'properties',
20
+ 'makefile': 'makefile',
21
+ 'nginx.conf': 'nginx',
22
+ }
23
+
24
+ const LANGUAGE_ALIASES: Readonly<Record<string, string>> = {
25
+ bash: 'shell',
26
+ 'c#': 'cs',
27
+ csharp: 'cs',
28
+ env: 'properties',
29
+ fish: 'shell',
30
+ handlebars: 'handlebars',
31
+ htm: 'html',
32
+ js: 'javascript',
33
+ jsonc: 'json',
34
+ json5: 'json',
35
+ log: 'text',
36
+ make: 'makefile',
37
+ md: 'markdown',
38
+ mk: 'makefile',
39
+ plaintext: 'text',
40
+ proto3: 'proto',
41
+ ps1: 'powershell',
42
+ psm1: 'powershell',
43
+ psd1: 'powershell',
44
+ py: 'python',
45
+ pyw: 'python',
46
+ pyi: 'python',
47
+ rbw: 'ruby',
48
+ sh: 'shell',
49
+ shellsession: 'shell',
50
+ ts: 'typescript',
51
+ text: 'text',
52
+ txt: 'text',
53
+ yaml: 'yaml',
54
+ yml: 'yaml',
55
+ zsh: 'shell',
56
+ }
57
+
58
+ function normalizeDetectedToken(value: NullableText): string | null {
59
+ if (!value) return null
60
+ const normalized = value.trim().toLowerCase().replace(/^\./u, '')
61
+ return normalized ? LANGUAGE_ALIASES[normalized] ?? normalized : null
62
+ }
63
+
64
+ function resolveLanguageFromFilePath(filePath: NullableText): string | null {
65
+ if (!filePath) return null
66
+ const normalizedPath = filePath.trim().toLowerCase()
67
+ if (!normalizedPath) return null
68
+ const basename = normalizedPath.split('/').pop() ?? normalizedPath
69
+ const special = SPECIAL_FILENAMES[basename]
70
+ if (special !== undefined) return special
71
+ if (basename.startsWith('dockerfile.')) return 'dockerfile'
72
+ if (!basename.includes('.')) return null
73
+ return normalizeDetectedToken(basename.split('.').pop())
74
+ }
75
+
76
+ /**
77
+ * Разрешает стабильную language identity без загрузки editor/highlighter runtime.
78
+ * Resolves stable language identity without loading editor or highlighter runtime.
79
+ */
80
+ export function resolveCodeLanguageKey(input: CodeEditorLanguageContract): string {
81
+ const language = validateCodeEditorLanguage('codeLanguages', input)
82
+ if (language.mode === 'explicit') return LANGUAGE_ALIASES[language.id] ?? language.id
83
+ const detected = resolveLanguageFromFilePath(language.filePath)
84
+ if (detected !== null) return detected
85
+ throw new RangeError(
86
+ `codeLanguages: невозможно определить язык по filePath ${JSON.stringify(language.filePath)}. `
87
+ + `/ codeLanguages: cannot detect a language from filePath ${JSON.stringify(language.filePath)}.`,
88
+ )
89
+ }
@@ -0,0 +1 @@
1
+ export { default } from '../components/shared/data-display/SCodeEditor.vue';
@@ -61,8 +61,6 @@ function enumerableDataEntries(
61
61
  }
62
62
 
63
63
  function validateDenseScalarArray(
64
- owner: string,
65
- coordinate: string,
66
64
  value: readonly unknown[],
67
65
  allowNullish: boolean,
68
66
  ): boolean {
@@ -90,7 +88,7 @@ function validateRouteDictionary(
90
88
  }
91
89
  for (const [key, candidate] of enumerableDataEntries(owner, coordinate, value)) {
92
90
  const validArray = Array.isArray(candidate)
93
- && validateDenseScalarArray(owner, `${coordinate}.${key}`, candidate, allowNullishArrayValues)
91
+ && validateDenseScalarArray(candidate, allowNullishArrayValues)
94
92
  if (!isRouteScalar(candidate) && !validArray) {
95
93
  throw new TypeError(
96
94
  `${owner}: ${coordinate}.${key} должен быть scalar или массивом scalar `
@@ -282,6 +282,7 @@ export const ownedAttributeSchemas = Object.freeze({
282
282
  'data-testid': 'data',
283
283
  }),
284
284
  SMetricCard: defineOwnedAttributeSchema({}),
285
+ SChart: defineOwnedAttributeSchema({}),
285
286
  SProgressBar: defineOwnedAttributeSchema({}),
286
287
  SProgressIndicator: defineOwnedAttributeSchema({}),
287
288
  SSectionHeader: defineOwnedAttributeSchema({}),
@@ -1,4 +1,4 @@
1
- import { computed, onMounted, ref, useId, watch } from 'vue'
1
+ import { computed, onMounted, ref, useId, watch, type ComponentPublicInstance } from 'vue'
2
2
 
3
3
  import { resolveOptionalDomId } from './runtimeContract'
4
4
 
@@ -44,6 +44,13 @@ export function useBinaryInput(options: BinaryInputOptions) {
44
44
  inputEl.value.indeterminate = (options.indeterminate?.() ?? false) && !checkedValue.value
45
45
  }
46
46
  }
47
+ const setInputElement = (element: Element | ComponentPublicInstance | null): void => {
48
+ if (element !== null && !(element instanceof HTMLInputElement)) {
49
+ throw new TypeError(`${options.owner}: template ref owner must be the native ${options.inputName} input`)
50
+ }
51
+ inputEl.value = element
52
+ applyIndeterminate()
53
+ }
47
54
  onMounted(applyIndeterminate)
48
55
  watch([options.indeterminate ?? (() => false), checkedValue], applyIndeterminate)
49
56
 
@@ -68,9 +75,9 @@ export function useBinaryInput(options: BinaryInputOptions) {
68
75
 
69
76
  return {
70
77
  checkedValue,
71
- inputEl,
72
78
  inputId,
73
79
  onChange,
74
80
  onClick,
81
+ setInputElement,
75
82
  } as const
76
83
  }
@@ -0,0 +1,3 @@
1
+ @import "./style.css";
2
+ @plugin "@tailwindcss/typography";
3
+ @custom-variant dark (&:where(.dark, .dark *));
@@ -268,6 +268,23 @@
268
268
  --s-code-editor-search-match-selected-background: rgb(16 185 129 / 35%);
269
269
  --s-code-editor-search-match-selected-outline: rgb(16 185 129 / 55%);
270
270
 
271
+ /* Semantic chart palette and geometry surfaces */
272
+ --s-chart-series-1: var(--color-primary-600);
273
+ --s-chart-series-2: #0f766e;
274
+ --s-chart-series-3: #d97706;
275
+ --s-chart-series-4: #7c3aed;
276
+ --s-chart-series-5: #e11d48;
277
+ --s-chart-series-6: #0891b2;
278
+ --s-chart-series-7: #65a30d;
279
+ --s-chart-series-8: var(--color-surface-600);
280
+ --s-chart-surface: var(--color-surface);
281
+ --s-chart-grid: color-mix(in srgb, var(--color-border) 60%, transparent);
282
+ --s-chart-axis: var(--color-border);
283
+ --s-chart-label: var(--color-text-muted);
284
+ --s-chart-axis-title: var(--color-text);
285
+ --s-chart-center-label: var(--color-text);
286
+ --s-chart-label-on-series: var(--color-surface-0);
287
+
271
288
  /* Sanitized document presentation */
272
289
  --s-document-code-surface: var(--color-surface-muted);
273
290
  --s-document-code-foreground: var(--color-text);
@@ -732,6 +749,22 @@
732
749
  :root[data-theme="pink-dark"],
733
750
  :root[data-theme="green-dark"],
734
751
  .dark {
752
+ --s-chart-series-1: var(--color-primary-400);
753
+ --s-chart-series-2: #2dd4bf;
754
+ --s-chart-series-3: #fbbf24;
755
+ --s-chart-series-4: #a78bfa;
756
+ --s-chart-series-5: #fb7185;
757
+ --s-chart-series-6: #22d3ee;
758
+ --s-chart-series-7: #a3e635;
759
+ --s-chart-series-8: var(--color-surface-300);
760
+ --s-chart-surface: var(--color-surface-900);
761
+ --s-chart-grid: color-mix(in srgb, var(--color-border) 72%, transparent);
762
+ --s-chart-axis: var(--color-surface-600);
763
+ --s-chart-label: var(--color-surface-300);
764
+ --s-chart-axis-title: var(--color-surface-100);
765
+ --s-chart-center-label: var(--color-surface-100);
766
+ --s-chart-label-on-series: var(--color-surface-950);
767
+
735
768
  --s-field-disabled-foreground: var(--color-surface-300);
736
769
 
737
770
  --s-menu-item-foreground: var(--color-surface-200);