ds-one 0.1.11-alpha.1 → 0.1.11-alpha.10

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 (37) hide show
  1. package/DS1/0-face/2025-04-23-device.ts +117 -1
  2. package/DS1/1-root/fonts/GT-America-Compressed-Regular.woff2 +0 -0
  3. package/DS1/1-root/one.css +10 -1
  4. package/DS1/2-core/{text-v1.ts → ds-text.ts} +4 -4
  5. package/DS1/2-core/home-v1.ts +2 -2
  6. package/DS1/3-unit/doublenav-v1.ts +2 -2
  7. package/DS1/3-unit/singlenav-v1.ts +1 -1
  8. package/DS1/4-page/ds-grid.ts +16 -4
  9. package/DS1/4-page/ds-layout.ts +1 -20
  10. package/DS1/index.ts +7 -1
  11. package/DS1/utils/cdn-loader.ts +5 -0
  12. package/DS1/utils/keys.json +41 -1
  13. package/README.md +5 -5
  14. package/dist/0-face/2025-04-23-device.d.ts +24 -0
  15. package/dist/0-face/2025-04-23-device.d.ts.map +1 -1
  16. package/dist/0-face/2025-04-23-device.js +84 -1
  17. package/dist/2-core/ds-text.d.ts +48 -0
  18. package/dist/2-core/ds-text.d.ts.map +1 -0
  19. package/dist/2-core/ds-text.js +83 -0
  20. package/dist/2-core/home-v1.js +2 -2
  21. package/dist/3-unit/doublenav-v1.js +2 -2
  22. package/dist/3-unit/singlenav-v1.js +1 -1
  23. package/dist/4-page/ds-grid.d.ts.map +1 -1
  24. package/dist/4-page/ds-grid.js +16 -4
  25. package/dist/4-page/ds-layout.d.ts.map +1 -1
  26. package/dist/4-page/ds-layout.js +1 -20
  27. package/dist/ds-one.bundle.js +138 -33
  28. package/dist/ds-one.bundle.js.map +3 -3
  29. package/dist/ds-one.bundle.min.js +54 -61
  30. package/dist/ds-one.bundle.min.js.map +4 -4
  31. package/dist/index.d.ts +3 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +5 -1
  34. package/dist/utils/cdn-loader.d.ts.map +1 -1
  35. package/dist/utils/cdn-loader.js +5 -0
  36. package/dist/utils/keys.json +41 -1
  37. package/package.json +1 -1
@@ -1,4 +1,120 @@
1
1
  // 2025-04-23-device.ts
2
2
  // Device detection and context utilities
3
3
 
4
- // TODO: Implement device detection utilities
4
+ export type DeviceType = "mobile" | "tablet" | "desktop";
5
+
6
+ export interface DeviceInfo {
7
+ isMobile: boolean;
8
+ isTablet: boolean;
9
+ isDesktop: boolean;
10
+ isTouchCapable: boolean;
11
+ deviceType: DeviceType;
12
+ userAgent: string;
13
+ screenWidth: number;
14
+ screenHeight: number;
15
+ }
16
+
17
+ /**
18
+ * Comprehensive mobile device detection
19
+ * Combines user agent detection, touch capability, and viewport size
20
+ */
21
+ export function detectMobileDevice(): boolean {
22
+ if (typeof navigator === "undefined" || typeof window === "undefined") {
23
+ return false;
24
+ }
25
+
26
+ const nav = navigator as any;
27
+ const win = window as any;
28
+ const ua: string =
29
+ (nav && (nav.userAgent || nav.vendor)) || (win && win.opera) || "";
30
+
31
+ // User agent based detection
32
+ const uaMatchesMobile =
33
+ /Mobile|Android|iP(ad|hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)|Windows Phone|Phone|Tablet/i.test(
34
+ ua
35
+ );
36
+
37
+ // Touch capability detection
38
+ const touchPoints = (nav && nav.maxTouchPoints) || 0;
39
+ const isTouchCapable = touchPoints > 1;
40
+
41
+ // Viewport detection
42
+ const narrowViewport = win
43
+ ? Math.min(win.innerWidth || 0, win.innerHeight || 0) <= 820
44
+ : false;
45
+
46
+ return uaMatchesMobile || (isTouchCapable && narrowViewport);
47
+ }
48
+
49
+ /**
50
+ * Get detailed device information
51
+ */
52
+ export function getDeviceInfo(): DeviceInfo {
53
+ const isMobile = detectMobileDevice();
54
+ const nav = navigator as any;
55
+ const win = window as any;
56
+
57
+ const touchPoints = (nav && nav.maxTouchPoints) || 0;
58
+ const isTouchCapable = touchPoints > 1;
59
+
60
+ const screenWidth = win?.innerWidth || 0;
61
+ const screenHeight = win?.innerHeight || 0;
62
+ const isTablet = isMobile && Math.min(screenWidth, screenHeight) >= 600;
63
+
64
+ return {
65
+ isMobile,
66
+ isTablet,
67
+ isDesktop: !isMobile,
68
+ isTouchCapable,
69
+ deviceType: isMobile ? (isTablet ? "tablet" : "mobile") : "desktop",
70
+ userAgent: (nav && (nav.userAgent || nav.vendor)) || "",
71
+ screenWidth,
72
+ screenHeight,
73
+ };
74
+ }
75
+
76
+ /**
77
+ * Initialize device detection and log to console
78
+ */
79
+ export function initDeviceDetection(): DeviceInfo {
80
+ const deviceInfo = getDeviceInfo();
81
+
82
+ // Log device detection results
83
+ if (deviceInfo.isMobile) {
84
+ console.log(
85
+ `[DS one] Mobile device detected - ${deviceInfo.deviceType} (${deviceInfo.screenWidth}x${deviceInfo.screenHeight})`
86
+ );
87
+ } else {
88
+ console.log(
89
+ `[DS one] Desktop device detected (${deviceInfo.screenWidth}x${deviceInfo.screenHeight})`
90
+ );
91
+ }
92
+
93
+ // Log additional details in development mode
94
+ if (typeof window !== "undefined" && (window as any).DS_ONE_DEBUG) {
95
+ console.log("[DS one] Device Info:", {
96
+ type: deviceInfo.deviceType,
97
+ isMobile: deviceInfo.isMobile,
98
+ isTablet: deviceInfo.isTablet,
99
+ isDesktop: deviceInfo.isDesktop,
100
+ isTouchCapable: deviceInfo.isTouchCapable,
101
+ viewport: `${deviceInfo.screenWidth}x${deviceInfo.screenHeight}`,
102
+ userAgent: deviceInfo.userAgent,
103
+ });
104
+ }
105
+
106
+ return deviceInfo;
107
+ }
108
+
109
+ // Auto-initialize when module loads
110
+ if (typeof window !== "undefined") {
111
+ // Wait for DOM to be ready
112
+ if (document.readyState === "loading") {
113
+ document.addEventListener("DOMContentLoaded", () => {
114
+ initDeviceDetection();
115
+ });
116
+ } else {
117
+ // DOM is already ready
118
+ initDeviceDetection();
119
+ }
120
+ }
@@ -1,3 +1,5 @@
1
+ /* version 0.1.11-alpha.8 */
2
+
1
3
  input {
2
4
  padding: 0;
3
5
  }
@@ -32,9 +34,10 @@ input {
32
34
  --ds1-docs-search-bg: light-dark(#f0f0f0, #171717);
33
35
  --ds1-docs-divider: light-dark(#e0e0e0, #000000);
34
36
 
35
- /* ezo-type */
37
+ /* typefaces */
36
38
  --typeface: "GT-America-Standard-Regular";
37
39
  --typeface-medium: "GT-America-Standard-Medium";
40
+ --typeface-compressed: "GT-America-Compressed-Regular";
38
41
  --typeface-japanese: "Noto Sans JP";
39
42
  --typeface-mono: "Iosevka";
40
43
  --type-size-default: calc(14px * var(--scaling-factor));
@@ -149,6 +152,12 @@ html {
149
152
  font-display: swap;
150
153
  }
151
154
 
155
+ @font-face {
156
+ font-family: GT-America-Compressed-Regular;
157
+ src: url("./fonts/GT-America-Compressed-Regular.woff2") format("woff2");
158
+ font-display: swap;
159
+ }
160
+
152
161
  .matrix__board {
153
162
  position: relative;
154
163
  top: calc(21.5px * var(--scaling-factor));
@@ -4,7 +4,7 @@ import { getText } from "../utils/language";
4
4
  /**
5
5
  * A component for displaying text from translations
6
6
  *
7
- * @element text-v1
7
+ * @element ds-text
8
8
  * @prop {string} key - The translation key to use
9
9
  * @prop {string} defaultValue - Default value if translation is not found
10
10
  * @prop {string} fallback - Optional fallback text if translation is not found (deprecated, use defaultValue)
@@ -35,7 +35,7 @@ export class Text extends LitElement {
35
35
  // Create bound event handlers for proper cleanup
36
36
  this.boundHandlers = {
37
37
  languageChanged: (() => {
38
- console.log("Language changed event received in text-v1");
38
+ console.log("Language changed event received in ds-text");
39
39
  this._loadText();
40
40
  }) as EventListener,
41
41
  };
@@ -112,10 +112,10 @@ export class Text extends LitElement {
112
112
  }
113
113
  }
114
114
 
115
- customElements.define("text-v1", Text);
115
+ customElements.define("ds-text", Text);
116
116
 
117
117
  declare global {
118
118
  interface HTMLElementTagNameMap {
119
- "text-v1": Text;
119
+ "ds-text": Text;
120
120
  }
121
121
  }
@@ -86,7 +86,7 @@ export class Home extends LitElement {
86
86
  }
87
87
 
88
88
  /* Inner text spacing without affecting the 80px outer width */
89
- .home > text-v1 {
89
+ .home > ds-text {
90
90
  padding: 0 calc(var(--1) * 0.15 * var(--scaling-factor));
91
91
  box-sizing: border-box;
92
92
  height: 100%;
@@ -152,7 +152,7 @@ export class Home extends LitElement {
152
152
  @click="${this._navigateHome}"
153
153
  @keydown="${this._onKeyDown}"
154
154
  >
155
- <text-v1 key="home"></text-v1>
155
+ <ds-text key="home"></ds-text>
156
156
  </div>
157
157
  `;
158
158
  }
@@ -80,14 +80,14 @@ export class DoubleNav extends LitElement {
80
80
  ? html`
81
81
  <a href="${this.previous}" class="nav-previous">
82
82
  <icon-v1 type="left"></icon-v1>
83
- <text-v1>${this.previousText || "Previous"}</text-v1>
83
+ <ds-text>${this.previousText || "Previous"}</ds-text>
84
84
  </a>
85
85
  `
86
86
  : html`<div></div>`}
87
87
  ${this.next
88
88
  ? html`
89
89
  <a href="${this.next}" class="nav-next">
90
- <text-v1>${this.nextText || "Next"}</text-v1>
90
+ <ds-text>${this.nextText || "Next"}</ds-text>
91
91
  <icon-v1 type="right"></icon-v1>
92
92
  </a>
93
93
  `
@@ -47,7 +47,7 @@ export class SingleNav extends LitElement {
47
47
 
48
48
  return html`
49
49
  <a href="${href}">
50
- <text-v1 key="${navConfig.key}"></text-v1>
50
+ <ds-text key="${navConfig.key}"></ds-text>
51
51
  <icon-v1 type="right"></icon-v1>
52
52
  </a>
53
53
  `;
@@ -22,7 +22,7 @@ export class Grid extends LitElement {
22
22
  margin-top: 0.5px !important;
23
23
  margin-left: 0.5px !important;
24
24
  display: grid;
25
- width: 100%;
25
+ width: 1440px;
26
26
  height: 100%;
27
27
  grid-template-columns: repeat(auto-fill, 19px);
28
28
  grid-template-rows: repeat(auto-fill, 19px);
@@ -32,7 +32,7 @@ export class Grid extends LitElement {
32
32
  column-rule: 1px solid
33
33
  light-dark(rgba(0, 0, 0, 0.03), rgba(238, 238, 238, 0.022));
34
34
  outline: 1px solid light-dark(rgba(0, 0, 0, 0.15), #100101e7);
35
- position: absolute;
35
+ position: fixed;
36
36
  top: 0;
37
37
  left: 50%;
38
38
  transform: translateX(-50%);
@@ -40,6 +40,17 @@ export class Grid extends LitElement {
40
40
  z-index: 300;
41
41
  }
42
42
 
43
+ /* Mobile styles - 15 columns with smaller gap */
44
+ @media (max-width: 768px) {
45
+ :host {
46
+ width: 100%;
47
+ max-width: 375px;
48
+ grid-template-columns: repeat(15, 1fr);
49
+ grid-template-rows: repeat(auto-fill, 20px);
50
+ gap: 0.5px;
51
+ }
52
+ }
53
+
43
54
  :host([align="left"]) {
44
55
  left: 0;
45
56
  transform: none;
@@ -51,8 +62,9 @@ export class Grid extends LitElement {
51
62
  }
52
63
 
53
64
  :host([align="right"]) {
54
- left: 100%;
55
- transform: translateX(-100%);
65
+ left: auto;
66
+ right: 0;
67
+ transform: none;
56
68
  }
57
69
  `;
58
70
 
@@ -39,7 +39,7 @@ export class Layout extends LitElement {
39
39
  ". footer ."
40
40
  ". . .";
41
41
  min-height: 600px;
42
- background-color: rgba(235, 231, 231, 0.44);
42
+ background-color: rgba(165, 165, 165, 0.03);
43
43
  position: relative;
44
44
  width: 100%;
45
45
  max-width: 640px;
@@ -75,10 +75,6 @@ export class Layout extends LitElement {
75
75
  justify-self: end;
76
76
  }
77
77
 
78
- :host([mode="debug"]) {
79
- background-color: rgba(200, 114, 114, 0.1);
80
- }
81
-
82
78
  .debug-overlay {
83
79
  position: absolute;
84
80
  margin-left: -1px;
@@ -127,7 +123,6 @@ export class Layout extends LitElement {
127
123
  font-size: 10px;
128
124
  font-weight: var(--type-weight-default);
129
125
  font-family: var(--typeface);
130
- background-color: var(--slate);
131
126
  color: var(--black);
132
127
  border: 1px solid red;
133
128
  opacity: 1;
@@ -135,53 +130,39 @@ export class Layout extends LitElement {
135
130
 
136
131
  .debug-square {
137
132
  grid-area: square;
138
- background-color: rgba(255, 0, 0, 0.2);
139
133
  }
140
134
 
141
135
  .debug-title {
142
136
  grid-area: title;
143
- background-color: rgba(0, 255, 0, 0.2);
144
137
  }
145
138
 
146
139
  .debug-header {
147
140
  grid-area: header;
148
- background-color: rgba(0, 0, 255, 0.2);
149
141
  border-color: #0000ff;
150
142
  }
151
143
 
152
144
  .debug-projects {
153
145
  grid-area: projects;
154
- background-color: rgba(255, 255, 0, 0.2);
155
146
  border-color: #ffff00;
156
147
  }
157
148
 
158
149
  .debug-bio {
159
150
  grid-area: bio;
160
- background-color: rgba(255, 0, 255, 0.2);
161
151
  border-color: #ff00ff;
162
152
  }
163
153
 
164
154
  .debug-nav {
165
155
  grid-area: nav;
166
- background-color: rgba(0, 255, 255, 0.2);
167
156
  border-color: #00ffff;
168
157
  }
169
158
 
170
159
  .debug-footer {
171
160
  grid-area: footer;
172
- background-color: rgba(255, 165, 0, 0.2);
173
161
  border-color: #ffa500;
174
162
  }
175
163
 
176
- .debug-header {
177
- grid-area: header;
178
- background-color: rgba(0, 0, 255, 0.2);
179
- border-color: #0000ff;
180
- }
181
-
182
164
  .debug-content {
183
165
  grid-area: content;
184
- background-color: rgba(21, 169, 21, 0.57);
185
166
  border-color: rgba(71, 231, 71, 0.63);
186
167
  }
187
168
  `;
package/DS1/index.ts CHANGED
@@ -1,12 +1,15 @@
1
1
  // DS one - Main entry point for all components
2
2
  // Export all components for easy importing
3
3
 
4
+ // Initialize device detection (will auto-detect and log on load)
5
+ import "./0-face/2025-04-23-device";
6
+
4
7
  // Initialize CDN loader (will auto-load external translations if available)
5
8
  import "./utils/cdn-loader";
6
9
 
7
10
  // Core components
8
11
  export * from "./2-core/ds-button";
9
- export * from "./2-core/text-v1";
12
+ export * from "./2-core/ds-text";
10
13
  export * from "./2-core/icon-v1";
11
14
  export * from "./2-core/link-v1";
12
15
  export * from "./2-core/cycle-v1";
@@ -42,3 +45,6 @@ export * from "./utils/viewMode";
42
45
  export * from "./utils/settings";
43
46
  export * from "./utils/pricing";
44
47
  export * from "./utils/scroll";
48
+
49
+ // Device detection
50
+ export * from "./0-face/2025-04-23-device";
@@ -124,13 +124,16 @@ async function fetchTranslationFile(
124
124
  source: string
125
125
  ): Promise<TranslationMap | null> {
126
126
  try {
127
+ console.log(`[DS one] Attempting to fetch translations from: ${source}`);
127
128
  const response = await fetch(source);
128
129
 
129
130
  if (!response.ok) {
131
+ console.log(`[DS one] Failed to fetch ${source} (${response.status})`);
130
132
  return null;
131
133
  }
132
134
 
133
135
  const translations = await response.json();
136
+ console.log(`[DS one] Successfully fetched JSON from ${source}`);
134
137
 
135
138
  if (!validateTranslationMap(translations)) {
136
139
  console.warn(
@@ -145,12 +148,14 @@ async function fetchTranslationFile(
145
148
  return null;
146
149
  }
147
150
 
151
+ console.log(`[DS one] Valid translations found: ${languages.join(", ")}`);
148
152
  return translations;
149
153
  } catch (error) {
150
154
  if (
151
155
  error instanceof TypeError &&
152
156
  error.message.includes("Failed to fetch")
153
157
  ) {
158
+ console.log(`[DS one] Network error fetching ${source}`);
154
159
  return null;
155
160
  }
156
161
 
@@ -1 +1,41 @@
1
- {}
1
+ {
2
+ "en": {
3
+ "language": "Language",
4
+ "theme": "Theme",
5
+ "home": "Home",
6
+ "about": "About",
7
+ "contact": "Contact",
8
+ "welcome": "Welcome",
9
+ "description": "Description",
10
+ "learnMore": "Learn More",
11
+ "copyright": "© 2025",
12
+ "siteTitle": "Site Title",
13
+ "downloadCV": "Download CV"
14
+ },
15
+ "da": {
16
+ "language": "Sprog",
17
+ "theme": "Tema",
18
+ "home": "Hjem",
19
+ "about": "Om",
20
+ "contact": "Kontakt",
21
+ "welcome": "Velkommen",
22
+ "description": "Beskrivelse",
23
+ "learnMore": "Lær Mere",
24
+ "copyright": "© 2025",
25
+ "siteTitle": "Site Titel",
26
+ "downloadCV": "Download CV"
27
+ },
28
+ "ja": {
29
+ "language": "言語",
30
+ "theme": "テーマ",
31
+ "home": "ホーム",
32
+ "about": "について",
33
+ "contact": "お問い合わせ",
34
+ "welcome": "ようこそ",
35
+ "description": "説明",
36
+ "learnMore": "詳細を見る",
37
+ "copyright": "© 2025",
38
+ "siteTitle": "サイトタイトル",
39
+ "downloadCV": "CVをダウンロード"
40
+ }
41
+ }
package/README.md CHANGED
@@ -6,7 +6,7 @@ Build modern UIs with web components!
6
6
 
7
7
  [![npm version](https://badge.fury.io/js/ds-one.svg)](https://badge.fury.io/js/ds-one)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
- [![Version](https://img.shields.io/badge/version-0.1.11--alpha.0-orange.svg)](https://github.com/Jo4712/ds-one)
9
+ [![Version](https://img.shields.io/badge/version-0.1.11--alpha.1-orange.svg)](https://github.com/Jo4712/ds-one)
10
10
 
11
11
  **DS one** is a modern design system that provides a comprehensive set of reusable UI components built with Web Components. Think "Material Design meets Web Standards"—a simple, accessible component library that works with any framework or vanilla JavaScript.
12
12
 
@@ -27,7 +27,7 @@ npm install ds-one@alpha
27
27
  yarn add ds-one@alpha
28
28
  ```
29
29
 
30
- **Note**: Currently published as alpha version `0.1.11-alpha.0`. Use `@alpha` tag to install.
30
+ **Note**: Currently published as alpha version `0.1.11-alpha.10`. Use `@alpha` tag to install.
31
31
 
32
32
  ### Basic Usage
33
33
 
@@ -45,12 +45,12 @@ yarn add ds-one@alpha
45
45
  ></script>
46
46
  <script
47
47
  type="module"
48
- src="node_modules/design-system-one/2 Core/text-v1.ts"
48
+ src="node_modules/design-system-one/2 Core/ds-text.ts"
49
49
  ></script>
50
50
  </head>
51
51
  <body>
52
52
  <ds-button variant="primary" key="welcomeButton">Get Started</ds-button>
53
- <text-v1 variant="heading" key="mainHeading">Welcome to DS one</text-v1>
53
+ <ds-text variant="heading" key="mainHeading">Welcome to DS one</ds-text>
54
54
  </body>
55
55
  </html>
56
56
  ```
@@ -96,7 +96,7 @@ Try DS one in your browser: **[dsone.dev](https://dsone.dev)** (documentation sl
96
96
 
97
97
  ### Completed Features
98
98
 
99
- - ✅ Core component library (ds-button, text-v1, icon-v1, etc.)
99
+ - ✅ Core component library (ds-button, ds-text, icon-v1, etc.)
100
100
  - ✅ Theming system with accent color support
101
101
  - ✅ Internationalization with language keys
102
102
  - ✅ Responsive design with mobile scaling
@@ -1 +1,25 @@
1
+ export type DeviceType = "mobile" | "tablet" | "desktop";
2
+ export interface DeviceInfo {
3
+ isMobile: boolean;
4
+ isTablet: boolean;
5
+ isDesktop: boolean;
6
+ isTouchCapable: boolean;
7
+ deviceType: DeviceType;
8
+ userAgent: string;
9
+ screenWidth: number;
10
+ screenHeight: number;
11
+ }
12
+ /**
13
+ * Comprehensive mobile device detection
14
+ * Combines user agent detection, touch capability, and viewport size
15
+ */
16
+ export declare function detectMobileDevice(): boolean;
17
+ /**
18
+ * Get detailed device information
19
+ */
20
+ export declare function getDeviceInfo(): DeviceInfo;
21
+ /**
22
+ * Initialize device detection and log to console
23
+ */
24
+ export declare function initDeviceDetection(): DeviceInfo;
1
25
  //# sourceMappingURL=2025-04-23-device.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"2025-04-23-device.d.ts","sourceRoot":"","sources":["../../DS1/0-face/2025-04-23-device.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"2025-04-23-device.d.ts","sourceRoot":"","sources":["../../DS1/0-face/2025-04-23-device.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEzD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CA0B5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAsB1C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,UAAU,CA4BhD"}
@@ -1,3 +1,86 @@
1
1
  // 2025-04-23-device.ts
2
2
  // Device detection and context utilities
3
- // TODO: Implement device detection utilities
3
+ /**
4
+ * Comprehensive mobile device detection
5
+ * Combines user agent detection, touch capability, and viewport size
6
+ */
7
+ export function detectMobileDevice() {
8
+ if (typeof navigator === "undefined" || typeof window === "undefined") {
9
+ return false;
10
+ }
11
+ const nav = navigator;
12
+ const win = window;
13
+ const ua = (nav && (nav.userAgent || nav.vendor)) || (win && win.opera) || "";
14
+ // User agent based detection
15
+ const uaMatchesMobile = /Mobile|Android|iP(ad|hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)|Windows Phone|Phone|Tablet/i.test(ua);
16
+ // Touch capability detection
17
+ const touchPoints = (nav && nav.maxTouchPoints) || 0;
18
+ const isTouchCapable = touchPoints > 1;
19
+ // Viewport detection
20
+ const narrowViewport = win
21
+ ? Math.min(win.innerWidth || 0, win.innerHeight || 0) <= 820
22
+ : false;
23
+ return uaMatchesMobile || (isTouchCapable && narrowViewport);
24
+ }
25
+ /**
26
+ * Get detailed device information
27
+ */
28
+ export function getDeviceInfo() {
29
+ const isMobile = detectMobileDevice();
30
+ const nav = navigator;
31
+ const win = window;
32
+ const touchPoints = (nav && nav.maxTouchPoints) || 0;
33
+ const isTouchCapable = touchPoints > 1;
34
+ const screenWidth = win?.innerWidth || 0;
35
+ const screenHeight = win?.innerHeight || 0;
36
+ const isTablet = isMobile && Math.min(screenWidth, screenHeight) >= 600;
37
+ return {
38
+ isMobile,
39
+ isTablet,
40
+ isDesktop: !isMobile,
41
+ isTouchCapable,
42
+ deviceType: isMobile ? (isTablet ? "tablet" : "mobile") : "desktop",
43
+ userAgent: (nav && (nav.userAgent || nav.vendor)) || "",
44
+ screenWidth,
45
+ screenHeight,
46
+ };
47
+ }
48
+ /**
49
+ * Initialize device detection and log to console
50
+ */
51
+ export function initDeviceDetection() {
52
+ const deviceInfo = getDeviceInfo();
53
+ // Log device detection results
54
+ if (deviceInfo.isMobile) {
55
+ console.log(`[DS one] Mobile device detected - ${deviceInfo.deviceType} (${deviceInfo.screenWidth}x${deviceInfo.screenHeight})`);
56
+ }
57
+ else {
58
+ console.log(`[DS one] Desktop device detected (${deviceInfo.screenWidth}x${deviceInfo.screenHeight})`);
59
+ }
60
+ // Log additional details in development mode
61
+ if (typeof window !== "undefined" && window.DS_ONE_DEBUG) {
62
+ console.log("[DS one] Device Info:", {
63
+ type: deviceInfo.deviceType,
64
+ isMobile: deviceInfo.isMobile,
65
+ isTablet: deviceInfo.isTablet,
66
+ isDesktop: deviceInfo.isDesktop,
67
+ isTouchCapable: deviceInfo.isTouchCapable,
68
+ viewport: `${deviceInfo.screenWidth}x${deviceInfo.screenHeight}`,
69
+ userAgent: deviceInfo.userAgent,
70
+ });
71
+ }
72
+ return deviceInfo;
73
+ }
74
+ // Auto-initialize when module loads
75
+ if (typeof window !== "undefined") {
76
+ // Wait for DOM to be ready
77
+ if (document.readyState === "loading") {
78
+ document.addEventListener("DOMContentLoaded", () => {
79
+ initDeviceDetection();
80
+ });
81
+ }
82
+ else {
83
+ // DOM is already ready
84
+ initDeviceDetection();
85
+ }
86
+ }
@@ -0,0 +1,48 @@
1
+ import { LitElement } from "lit";
2
+ /**
3
+ * A component for displaying text from translations
4
+ *
5
+ * @element ds-text
6
+ * @prop {string} key - The translation key to use
7
+ * @prop {string} defaultValue - Default value if translation is not found
8
+ * @prop {string} fallback - Optional fallback text if translation is not found (deprecated, use defaultValue)
9
+ */
10
+ export declare class Text extends LitElement {
11
+ static get properties(): {
12
+ key: {
13
+ type: StringConstructor;
14
+ reflect: boolean;
15
+ };
16
+ defaultValue: {
17
+ type: StringConstructor;
18
+ reflect: boolean;
19
+ attribute: string;
20
+ };
21
+ fallback: {
22
+ type: StringConstructor;
23
+ reflect: boolean;
24
+ };
25
+ _text: {
26
+ type: StringConstructor;
27
+ state: boolean;
28
+ };
29
+ };
30
+ key: string;
31
+ defaultValue: string;
32
+ fallback: string;
33
+ _text: string;
34
+ private boundHandlers;
35
+ constructor();
36
+ static styles: import("lit").CSSResult;
37
+ connectedCallback(): void;
38
+ disconnectedCallback(): void;
39
+ updated(changedProperties: Map<string, unknown>): void;
40
+ _loadText(): void;
41
+ render(): import("lit-html").TemplateResult<1>;
42
+ }
43
+ declare global {
44
+ interface HTMLElementTagNameMap {
45
+ "ds-text": Text;
46
+ }
47
+ }
48
+ //# sourceMappingURL=ds-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ds-text.d.ts","sourceRoot":"","sources":["../../DS1/2-core/ds-text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C;;;;;;;GAOG;AACH,qBAAa,IAAK,SAAQ,UAAU;IAClC,MAAM,KAAK,UAAU;;;;;;;;;;;;;;;;;;MAOpB;IAEO,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,aAAa,CAAqC;;IAkB1D,MAAM,CAAC,MAAM,0BAQX;IAEF,iBAAiB;IAoBjB,oBAAoB;IAYpB,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAQ/C,SAAS;IAgBT,MAAM;CAGP;AAID,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,IAAI,CAAC;KACjB;CACF"}