From a5102140f34fe88e97cbc5fef88c9e4519f8fd47 Mon Sep 17 00:00:00 2001 From: Michele Riva Date: Mon, 12 Aug 2024 15:43:05 -0700 Subject: [PATCH 1/6] chore: updates version for release --- package.json | 2 +- packages/ui-stencil-angular/package.json | 2 +- .../projects/component-library/package.json | 2 +- packages/ui-stencil-react/package.json | 2 +- packages/ui-stencil-vue/package.json | 2 +- packages/ui-stencil/package.json | 2 +- .../ui-stencil/src/components/internal/orama-chat/readme.md | 2 +- packages/ui-stencil/src/components/orama-chat-box/readme.md | 2 +- packages/ui-stencil/src/components/orama-search-box/readme.md | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 6669594f..969c9baf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "stencil-design-system", - "version": "0.0.8", + "version": "0.0.9", "scripts": { "build": "turbo run build", "build:storybook": "turbo run build --filter=storybook", diff --git a/packages/ui-stencil-angular/package.json b/packages/ui-stencil-angular/package.json index 07c82c24..b9390109 100644 --- a/packages/ui-stencil-angular/package.json +++ b/packages/ui-stencil-angular/package.json @@ -1,7 +1,7 @@ { "private": false, "name": "@orama/angular-components", - "version": "0.0.8", + "version": "0.0.9", "description": "Angular components for Orama Cloud", "license": "Apache-2.0", "scripts": { diff --git a/packages/ui-stencil-angular/projects/component-library/package.json b/packages/ui-stencil-angular/projects/component-library/package.json index c7169b6a..b31d1b13 100644 --- a/packages/ui-stencil-angular/projects/component-library/package.json +++ b/packages/ui-stencil-angular/projects/component-library/package.json @@ -1,6 +1,6 @@ { "name": "@orama/angular-components", - "version": "0.0.8", + "version": "0.0.9", "peerDependencies": { "@angular/common": "^16.1.0", "@angular/core": "^16.1.0", diff --git a/packages/ui-stencil-react/package.json b/packages/ui-stencil-react/package.json index c2f5aa4a..2f4e3d7a 100644 --- a/packages/ui-stencil-react/package.json +++ b/packages/ui-stencil-react/package.json @@ -1,6 +1,6 @@ { "name": "@orama/react-components", - "version": "0.0.8", + "version": "0.0.9", "description": "React components for Orama Cloud", "license": "Apache-2.0", "author": "", diff --git a/packages/ui-stencil-vue/package.json b/packages/ui-stencil-vue/package.json index d3c7b4b4..b639bc45 100644 --- a/packages/ui-stencil-vue/package.json +++ b/packages/ui-stencil-vue/package.json @@ -1,6 +1,6 @@ { "name": "@orama/vue-components", - "version": "0.0.8", + "version": "0.0.9", "description": "Vue components for Orama Cloud", "license": "Apache-2.0", "author": "", diff --git a/packages/ui-stencil/package.json b/packages/ui-stencil/package.json index ba4715d3..a9848bb9 100644 --- a/packages/ui-stencil/package.json +++ b/packages/ui-stencil/package.json @@ -1,6 +1,6 @@ { "name": "@orama/wc-components", - "version": "0.0.8", + "version": "0.0.9", "description": "UI web components for Orama Cloud", "license": "Apache-2.0", "repository": { diff --git a/packages/ui-stencil/src/components/internal/orama-chat/readme.md b/packages/ui-stencil/src/components/internal/orama-chat/readme.md index d977c94c..1ce294d0 100644 --- a/packages/ui-stencil/src/components/internal/orama-chat/readme.md +++ b/packages/ui-stencil/src/components/internal/orama-chat/readme.md @@ -14,7 +14,7 @@ | `placeholder` | `placeholder` | | `string` | `'Ask me anything'` | | `showClearChat` | `show-clear-chat` | | `boolean` | `true` | | `sourceBaseUrl` | `source-base-url` | | `string` | `''` | -| `sourcesMap` | -- | | `{ title?: string; description?: string; path?: string; }` | `undefined` | +| `sourcesMap` | -- | | `{ title?: string; path?: string; description?: string; }` | `undefined` | | `suggestions` | -- | | `string[]` | `undefined` | diff --git a/packages/ui-stencil/src/components/orama-chat-box/readme.md b/packages/ui-stencil/src/components/orama-chat-box/readme.md index 4cc80200..5a93b070 100644 --- a/packages/ui-stencil/src/components/orama-chat-box/readme.md +++ b/packages/ui-stencil/src/components/orama-chat-box/readme.md @@ -12,7 +12,7 @@ | `index` | -- | | `{ api_key: string; endpoint: string; }` | `undefined` | | `placeholder` | `placeholder` | | `string` | `undefined` | | `sourceBaseUrl` | `source-base-url` | | `string` | `undefined` | -| `sourcesMap` | -- | | `{ title?: string; description?: string; path?: string; }` | `undefined` | +| `sourcesMap` | -- | | `{ title?: string; path?: string; description?: string; }` | `undefined` | | `suggestions` | -- | | `string[]` | `undefined` | diff --git a/packages/ui-stencil/src/components/orama-search-box/readme.md b/packages/ui-stencil/src/components/orama-search-box/readme.md index 428a289c..24dc6af5 100644 --- a/packages/ui-stencil/src/components/orama-search-box/readme.md +++ b/packages/ui-stencil/src/components/orama-search-box/readme.md @@ -12,9 +12,9 @@ | `index` | -- | | `{ api_key: string; endpoint: string; }` | `undefined` | | `open` | `open` | | `boolean` | `false` | | `placeholder` | `placeholder` | | `string` | `undefined` | -| `resultMap` | -- | | `{ title?: string; description?: string; path?: string; section?: string; }` | `{}` | +| `resultMap` | -- | | `{ section?: string; title?: string; path?: string; description?: string; }` | `{}` | | `sourceBaseUrl` | `source-base-url` | | `string` | `undefined` | -| `sourcesMap` | -- | | `{ title?: string; description?: string; path?: string; }` | `undefined` | +| `sourcesMap` | -- | | `{ title?: string; path?: string; description?: string; }` | `undefined` | | `suggestions` | -- | | `string[]` | `undefined` | | `themeConfig` | -- | | `{ typography?: DeepPartial<{ '--font-primary': string; }>; colors?: DeepPartial<{ gray50: string; gray100: string; gray200: string; gray300: string; gray400: string; gray500: string; gray600: string; gray700: string; gray800: string; gray900: string; gray950: string; purple100: string; purple200: string; purple300: string; purple500: string; purple600: string; purple700: string; light: { "--text-color-primary": string; "--text-color-secondary": string; "--text-color-tertiary": string; "--text-color-accent": string; "--text-color-inactive": string; "--text-color-reverse": string; "--background-color-primary": string; "--background-color-secondary": string; "--background-color-tertiary": string; "--background-color-fourth": string; "--background-color-reverse": string; "--border-color-primary": string; "--border-color-secondary": string; "--border-color-tertiary": string; "--border-color-accent": string; "--icon-color-primary": string; "--icon-color-secondary": string; "--icon-color-tertiary": string; "--icon-color-inactive": string; "--icon-color-accent": string; "--shadow-color-primary": string; "--backdrop-background-color-primary": string; "--chat-button-border-color-gradientOne": string; "--chat-button-border-color-gradientTwo": string; "--chat-button-border-color-gradientThree": string; "--chat-button-border-color-gradientFour": string; "--chat-button-border-color-gradientFive": string; "--chat-button-border-color-gradientSix": string; "--chat-button-background-color-gradientOne": string; "--chat-button-background-color-gradientTwo": string; "--button-text-color-primary": string; "--button-text-color-secondary": string; "--button-text-color-inactive": string; "--button-background-color-primary": string; "--button-background-color-secondary": string; "--button-background-color-inactive": string; "--button-border-color-primary": string; "--button-border-color-secondary": string; "--button-border-color-inactive": string; }; dark: { "--text-color-primary": string; "--text-color-secondary": string; "--text-color-tertiary": string; "--text-color-accent": string; "--text-color-inactive": string; "--text-color-reverse": string; "--background-color-primary": string; "--background-color-secondary": string; "--background-color-tertiary": string; "--background-color-fourth": string; "--background-color-reverse": string; "--border-color-primary": string; "--border-color-secondary": string; "--border-color-tertiary": string; "--border-color-accent": string; "--icon-color-primary": string; "--icon-color-secondary": string; "--icon-color-tertiary": string; "--icon-color-inactive": string; "--icon-color-accent": string; "--shadow-color-primary": string; "--button-text-color-primary": string; "--button-background-color-primary": string; "--backdrop-background-color-primary": string; "--chat-button-border-color-gradientOne": string; "--chat-button-border-color-gradientTwo": string; "--chat-button-border-color-gradientThree": string; "--chat-button-border-color-gradientFour": string; "--chat-button-border-color-gradientFive": string; "--chat-button-border-color-gradientSix": string; "--chat-button-background-color-gradientOne": string; "--chat-button-background-color-gradientTwo": string; }; }>; }` | `undefined` | From 4a4b286dbf4a8564bb84487a0dd17e58b76e55c3 Mon Sep 17 00:00:00 2001 From: Francesca Giannino Date: Tue, 13 Aug 2024 10:59:44 +0200 Subject: [PATCH 2/6] feat: emit events on modal and searchbox status change --- apps/demo-react/src/App.tsx | 66 +++++++++++++++++-- apps/storybook/stories/config.ts | 3 + packages/ui-stencil-vue/lib/components.ts | 7 +- packages/ui-stencil/src/components.d.ts | 40 +++++++++++ .../internal/orama-chat/orama-chat.tsx | 2 +- .../components/internal/orama-chat/readme.md | 2 +- .../internal/orama-modal/orama-modal.scss | 2 +- .../internal/orama-modal/orama-modal.tsx | 38 +++++++++-- .../components/internal/orama-modal/readme.md | 18 +++-- .../orama-search-results.tsx | 3 +- .../internal/orama-search/orama-search.tsx | 2 +- .../orama-sliding-panel.tsx | 1 + .../src/components/orama-chat-box/readme.md | 2 +- .../orama-search-box/orama-search-box.tsx | 46 ++++++++++--- .../src/components/orama-search-box/readme.md | 7 ++ .../orama-search-button.tsx | 2 +- .../ui-stencil/src/services/ThemeService.ts | 0 17 files changed, 204 insertions(+), 37 deletions(-) create mode 100644 packages/ui-stencil/src/services/ThemeService.ts diff --git a/apps/demo-react/src/App.tsx b/apps/demo-react/src/App.tsx index 19bbacbd..79b638e3 100644 --- a/apps/demo-react/src/App.tsx +++ b/apps/demo-react/src/App.tsx @@ -1,23 +1,79 @@ +import React from 'react' +import { defineCustomElements, OramaChatBox, OramaSearchBox, OramaButton } from '@orama/react-components' import './App.css' -import { defineCustomElements, OramaChatBox } from '@orama/react-components' void defineCustomElements() function App() { + const [open, setOpen] = React.useState(false) return ( <>

App React

+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem + aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. + Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni + dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor + sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore + magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis + suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in + ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas + nulla pariatur? +

+
+

ChatBox in a section

+
+ +
+
+

Another section

+ { + setOpen(true) + }} + > + Open searchbox + +

+ At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti + atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique + sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum + facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil + impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor + repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et + voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, + ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat. +

+

+ At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti + atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique + sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum + facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil + impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor + repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et + voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, + ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat. +

-

ChatBox

- { + setOpen(false) + }} index={{ - api_key: 'yl2JSnjLNBV6FVfUWEyadpjFr6KzPiDR', - endpoint: 'https://cloud.orama.run/v1/indexes/recipes-m7w9mm', + api_key: 'LerNlbp6379jVKaPs4wt2nZT4MJZbU1J', + endpoint: 'https://cloud.orama.run/v1/indexes/docs-orama-b3f5xd', }} />
diff --git a/apps/storybook/stories/config.ts b/apps/storybook/stories/config.ts index 6857de52..2f965c96 100644 --- a/apps/storybook/stories/config.ts +++ b/apps/storybook/stories/config.ts @@ -4,6 +4,7 @@ export type DemoIndexConfig = Record const demoIndexes: DemoIndexConfig = { orama: { + open: true, index: { api_key: 'LerNlbp6379jVKaPs4wt2nZT4MJZbU1J', endpoint: 'https://cloud.orama.run/v1/indexes/docs-orama-b3f5xd', @@ -39,6 +40,7 @@ const demoIndexes: DemoIndexConfig = { }, }, recipes: { + open: true, index: { api_key: 'yl2JSnjLNBV6FVfUWEyadpjFr6KzPiDR', endpoint: 'https://cloud.orama.run/v1/indexes/recipes-m7w9mm', @@ -70,6 +72,7 @@ const demoIndexes: DemoIndexConfig = { }, }, videogames: { + open: true, index: { api_key: 'WL7pKdEqCTPf3G2412x8ecneqVbnkklr', endpoint: 'https://cloud.orama.foo/v1/indexes/videogames-rk139h', diff --git a/packages/ui-stencil-vue/lib/components.ts b/packages/ui-stencil-vue/lib/components.ts index 771e2624..2d5b59b4 100644 --- a/packages/ui-stencil-vue/lib/components.ts +++ b/packages/ui-stencil-vue/lib/components.ts @@ -111,7 +111,9 @@ export const OramaMarkdown = /*@__PURE__*/ defineContainer('o export const OramaModal = /*@__PURE__*/ defineContainer('orama-modal', undefined, [ 'open', 'closeOnEscape', - 'mainTitle' + 'closeOnOutsideClick', + 'mainTitle', + 'modalStatusChanged' ]); @@ -138,7 +140,8 @@ export const OramaSearchBox = /*@__PURE__*/ defineContainer( 'sourceBaseUrl', 'sourcesMap', 'placeholder', - 'suggestions' + 'suggestions', + 'searchboxClosed' ]); diff --git a/packages/ui-stencil/src/components.d.ts b/packages/ui-stencil/src/components.d.ts index 5ea32266..f82fd55c 100644 --- a/packages/ui-stencil/src/components.d.ts +++ b/packages/ui-stencil/src/components.d.ts @@ -10,6 +10,7 @@ import { CloudIndexConfig, ColorScheme, ResultMap, SearchResult, SearchResultByS import { TChatInteraction } from "./context/chatContext"; import { Facet } from "./components/internal/orama-facets/orama-facets"; import { InputProps } from "./components/internal/orama-input/orama-input"; +import { ModalStatus } from "./components/internal/orama-modal/orama-modal"; import { TThemeOverrides } from "./config/theme"; import { SearchResultsProps } from "./components/internal/orama-search-results/orama-search-results"; import { TextProps } from "./components/internal/orama-text/orama-text"; @@ -18,6 +19,7 @@ export { CloudIndexConfig, ColorScheme, ResultMap, SearchResult, SearchResultByS export { TChatInteraction } from "./context/chatContext"; export { Facet } from "./components/internal/orama-facets/orama-facets"; export { InputProps } from "./components/internal/orama-input/orama-input"; +export { ModalStatus } from "./components/internal/orama-modal/orama-modal"; export { TThemeOverrides } from "./config/theme"; export { SearchResultsProps } from "./components/internal/orama-search-results/orama-search-results"; export { TextProps } from "./components/internal/orama-text/orama-text"; @@ -96,6 +98,7 @@ export namespace Components { } interface OramaModal { "closeOnEscape": boolean; + "closeOnOutsideClick": boolean; "mainTitle": string; "open": boolean; } @@ -178,6 +181,14 @@ export interface OramaInputCustomEvent extends CustomEvent { detail: T; target: HTMLOramaInputElement; } +export interface OramaModalCustomEvent extends CustomEvent { + detail: T; + target: HTMLOramaModalElement; +} +export interface OramaSearchBoxCustomEvent extends CustomEvent { + detail: T; + target: HTMLOramaSearchBoxElement; +} export interface OramaSearchResultsCustomEvent extends CustomEvent { detail: T; target: HTMLOramaSearchResultsElement; @@ -278,7 +289,18 @@ declare global { prototype: HTMLOramaMarkdownElement; new (): HTMLOramaMarkdownElement; }; + interface HTMLOramaModalElementEventMap { + "modalStatusChanged": ModalStatus; + } interface HTMLOramaModalElement extends Components.OramaModal, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLOramaModalElement, ev: OramaModalCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLOramaModalElement, ev: OramaModalCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLOramaModalElement: { prototype: HTMLOramaModalElement; @@ -296,7 +318,20 @@ declare global { prototype: HTMLOramaSearchElement; new (): HTMLOramaSearchElement; }; + interface HTMLOramaSearchBoxElementEventMap { + "searchboxClosed": { + id: HTMLElement + }; + } interface HTMLOramaSearchBoxElement extends Components.OramaSearchBox, HTMLStencilElement { + addEventListener(type: K, listener: (this: HTMLOramaSearchBoxElement, ev: OramaSearchBoxCustomEvent) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLOramaSearchBoxElement, ev: OramaSearchBoxCustomEvent) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; } var HTMLOramaSearchBoxElement: { prototype: HTMLOramaSearchBoxElement; @@ -452,7 +487,9 @@ declare namespace LocalJSX { } interface OramaModal { "closeOnEscape"?: boolean; + "closeOnOutsideClick"?: boolean; "mainTitle"?: string; + "onModalStatusChanged"?: (event: OramaModalCustomEvent) => void; "open"?: boolean; } interface OramaNavigationBar { @@ -468,6 +505,9 @@ declare namespace LocalJSX { "colorScheme"?: ColorScheme; "facetProperty"?: string; "index"?: CloudIndexConfig; + "onSearchboxClosed"?: (event: OramaSearchBoxCustomEvent<{ + id: HTMLElement + }>) => void; "open"?: boolean; "placeholder"?: string; "resultMap"?: Partial; diff --git a/packages/ui-stencil/src/components/internal/orama-chat/orama-chat.tsx b/packages/ui-stencil/src/components/internal/orama-chat/orama-chat.tsx index ef95739d..9d2017e6 100644 --- a/packages/ui-stencil/src/components/internal/orama-chat/orama-chat.tsx +++ b/packages/ui-stencil/src/components/internal/orama-chat/orama-chat.tsx @@ -43,7 +43,7 @@ export class OramaChat { handleFocus = () => { if (this.focusInput) { - this.textareaRef.focus() + this.textareaRef?.focus() } } diff --git a/packages/ui-stencil/src/components/internal/orama-chat/readme.md b/packages/ui-stencil/src/components/internal/orama-chat/readme.md index d977c94c..1ce294d0 100644 --- a/packages/ui-stencil/src/components/internal/orama-chat/readme.md +++ b/packages/ui-stencil/src/components/internal/orama-chat/readme.md @@ -14,7 +14,7 @@ | `placeholder` | `placeholder` | | `string` | `'Ask me anything'` | | `showClearChat` | `show-clear-chat` | | `boolean` | `true` | | `sourceBaseUrl` | `source-base-url` | | `string` | `''` | -| `sourcesMap` | -- | | `{ title?: string; description?: string; path?: string; }` | `undefined` | +| `sourcesMap` | -- | | `{ title?: string; path?: string; description?: string; }` | `undefined` | | `suggestions` | -- | | `string[]` | `undefined` | diff --git a/packages/ui-stencil/src/components/internal/orama-modal/orama-modal.scss b/packages/ui-stencil/src/components/internal/orama-modal/orama-modal.scss index f90ff67d..982e2d6e 100644 --- a/packages/ui-stencil/src/components/internal/orama-modal/orama-modal.scss +++ b/packages/ui-stencil/src/components/internal/orama-modal/orama-modal.scss @@ -6,6 +6,7 @@ height: 100%; background-color: var(--backdrop-background-color-primary, palette('backdrop-background', 'primary')); display: none; + z-index: 9999; &.open { display: block; @@ -17,7 +18,6 @@ background-color: var(--background-color-primary, background-color('primary')); position: fixed; inset: 0; - z-index: 9999; flex-direction: column; justify-content: space-between; diff --git a/packages/ui-stencil/src/components/internal/orama-modal/orama-modal.tsx b/packages/ui-stencil/src/components/internal/orama-modal/orama-modal.tsx index 8424a9a2..2f08b2a5 100644 --- a/packages/ui-stencil/src/components/internal/orama-modal/orama-modal.tsx +++ b/packages/ui-stencil/src/components/internal/orama-modal/orama-modal.tsx @@ -1,15 +1,25 @@ -import { Component, h, Prop, State, Listen, Element } from '@stencil/core' +import { Component, h, Prop, State, Listen, Element, Event, type EventEmitter, Watch } from '@stencil/core' +export type ModalStatus = { + open: boolean + id: HTMLElement +} @Component({ tag: 'orama-modal', styleUrl: 'orama-modal.scss', scoped: true, }) export class OramaModal { - @Prop({ mutable: true }) open = false + @Prop() open = false @Prop() closeOnEscape = true + @Prop() closeOnOutsideClick = true @Prop() mainTitle = '' + @State() activeElement: HTMLElement + @State() modalIsOpen = this.open + + @Event() modalStatusChanged: EventEmitter + @Element() el: HTMLElement private firstFocusableElement: HTMLElement @@ -18,7 +28,8 @@ export class OramaModal { @Listen('keydown', { target: 'document' }) handleKeyDown(ev: KeyboardEvent) { - if (this.open) { + ev.stopPropagation() + if (this.modalIsOpen) { switch (ev.key) { case 'Tab': this.trapFocus(ev) @@ -40,6 +51,19 @@ export class OramaModal { } } + @Watch('modalIsOpen') + handleOpenChange(newValue: boolean) { + this.modalStatusChanged.emit({ + open: newValue, + id: this.el, + }) + } + + @Watch('open') + handleOpenPropChange(newValue: boolean) { + this.modalIsOpen = newValue + } + private trapFocus(event: KeyboardEvent) { const focusableElements = this.el.querySelectorAll( 'a[href], button, textarea, input, select, [tabindex]:not([tabindex="-1"])', @@ -78,11 +102,11 @@ export class OramaModal { } private closeModal() { - this.open = false + this.modalIsOpen = false } componentDidLoad() { - if (this.open) { + if (this.modalIsOpen) { this.activeElement = document.activeElement as HTMLElement this.handleFocus() } @@ -96,7 +120,7 @@ export class OramaModal { } componentDidUpdate() { - if (this.open) { + if (this.modalIsOpen) { this.handleFocus() } else if (this.activeElement) { this.activeElement.focus() @@ -134,7 +158,7 @@ export class OramaModal { render() { return (