forked from novuhq/novu
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(js): Introduce UI (novuhq#5746)
* feat(js): the base js sdk package scaffolding * feat(js): improve the package json exports and tsup config * feat(js): lazy session initialization and interface fixes * feat(js): renamed the *.spec.ts to *.test.ts * feat(js): js sdk feeds module * feat(js): the base js sdk package scaffolding * feat(js): set the dist file size limits and run the check after the build * feat(js): lazy session initialization and interface fixes * feat(js): renamed the *.spec.ts to *.test.ts * feat(js): js sdk feeds module * chore(js): simplified the notification and preference classes * feat(js): lazy session initialization and interface fixes * feat(js): the base js sdk package scaffolding * feat(js): js sdk feeds module * feat(js): handling the web socket connection and events * chore(js): removed old spec file * chore(js): fixed the package building on esm and cjs modules * feat: ui solid * revert: novu/js package * feat: implement solidjs * refactor: update file name * refactor: remove unused deps * refactor: rename app to inbox * refactor: rename ui to inboxui * feat: add ui to umd * feat: update tsup build and removed umd for ui * refactor: imports and babel * feat: add tailwind css * feat: add tailwind * feat: add vanilla * feat: add vanilla and fix tailwind build * chore: generate pnpm lock * chore: update * feat: remove emotion and vanilla-extract * feat: integrate appearance and variables into ui * feat: add ui demo * fix: tailwind classes * fix: Scope tailwind styles * fix: js package build * refactor: Cleanup css generation * feat(js): Create variable set * feat(js): Support multiple descriptors per element * chore: update lock * refactor: remove deleted files * chore: update lock file * chore: update lock file * fix: build * refactor: remove js package from web app * fix(js): Generate and expose default color css variables * feat(js): Auto enable darkmode when detected * fix(js): Revert dark mode support * chore(js): Remove tailwind-merge dep * chore(js): Use camelcase for components * fix(js): Avoid keeping old rules when regenerating * chore: update lock * chore: update lock * chore: update lock * fix: cspell --------- Co-authored-by: Paweł <[email protected]> Co-authored-by: George Desipris <[email protected]> Co-authored-by: desiprisg <[email protected]>
- Loading branch information
1 parent
79e319a
commit e173dbd
Showing
18 changed files
with
2,577 additions
and
276 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module.exports = { | ||
plugins: { | ||
autoprefixer: {}, | ||
tailwindcss: {}, | ||
'postcss-prefix-selector': { | ||
transform: function (_, selector) { | ||
// Prefix each class selector with :where(.class) | ||
if (selector.startsWith('.')) { | ||
return `:where(${selector})`; | ||
} | ||
|
||
return selector; // Return other selectors unchanged | ||
}, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const NOVU_CSS_IN_JS_STYLESHEET_ID = 'novu-css-in-js-appearance-styles'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Variables } from '../context'; | ||
|
||
export const defaultVariables: Required<Variables> = { | ||
colorPrimary: '#0081F1', | ||
colorPrimaryForeground: 'white', | ||
colorSecondary: '#F3F3F3', | ||
colorSecondaryForeground: '#1A1523', | ||
colorBackground: '#FFFFFF', | ||
colorForeground: '#1A1523', | ||
colorNeutral: 'black', | ||
fontSize: 'inherit', | ||
borderRadius: '0.375rem', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './constants'; | ||
export * from './default-appearance'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { ParentProps, createContext, createEffect, createSignal, onMount, useContext } from 'solid-js'; | ||
import { createStore } from 'solid-js/store'; | ||
import { NOVU_CSS_IN_JS_STYLESHEET_ID, defaultVariables } from '../config'; | ||
import { parseElements, parseVariables } from '../helpers'; | ||
|
||
export type CSSProperties = { | ||
[key: string]: string | number; | ||
}; | ||
|
||
export type ElementStyles = string | CSSProperties; | ||
|
||
export type Elements = { | ||
button?: ElementStyles; | ||
root?: ElementStyles; | ||
}; | ||
|
||
export type Variables = { | ||
colorBackground?: string; | ||
colorForeground?: string; | ||
colorPrimary?: string; | ||
colorPrimaryForeground?: string; | ||
colorSecondary?: string; | ||
colorSecondaryForeground?: string; | ||
colorNeutral?: string; | ||
fontSize?: string; | ||
borderRadius?: string; | ||
}; | ||
|
||
export type AppearanceContextType = { | ||
variables?: Variables; | ||
elements?: Elements; | ||
descriptorToCssInJsClass: Record<string, string>; | ||
}; | ||
|
||
const AppearanceContext = createContext<AppearanceContextType | undefined>(undefined); | ||
|
||
export type Appearance = Pick<AppearanceContextType, 'elements' | 'variables'>; | ||
|
||
type AppearanceProviderProps = ParentProps & Appearance; | ||
|
||
export const AppearanceProvider = (props: AppearanceProviderProps) => { | ||
const [store, setStore] = createStore<{ | ||
descriptorToCssInJsClass: Record<string, string>; | ||
}>({ descriptorToCssInJsClass: {} }); | ||
const [styleElement, setStyleElement] = createSignal<HTMLStyleElement | null>(null); | ||
const [elementRules, setElementRules] = createSignal<string[]>([]); | ||
const [variableRules, setVariableRules] = createSignal<string[]>([]); | ||
|
||
//place style element on HEAD. Placing in body is available for HTML 5.2 onward. | ||
onMount(() => { | ||
const styleEl = document.createElement('style'); | ||
styleEl.id = NOVU_CSS_IN_JS_STYLESHEET_ID; | ||
document.head.appendChild(styleEl); | ||
|
||
setStyleElement(styleEl); | ||
}); | ||
|
||
//handle variables | ||
createEffect(() => { | ||
const styleEl = styleElement(); | ||
|
||
if (!styleEl) { | ||
return; | ||
} | ||
|
||
setVariableRules(parseVariables({ ...defaultVariables, ...(props.variables || ({} as Variables)) })); | ||
}); | ||
|
||
//handle elements | ||
createEffect(() => { | ||
const styleEl = styleElement(); | ||
|
||
if (!styleEl) { | ||
return; | ||
} | ||
|
||
const elementsStyleData = parseElements(props.elements || {}); | ||
setStore('descriptorToCssInJsClass', (obj) => ({ | ||
...obj, | ||
...elementsStyleData.reduce<Record<string, string>>((acc, item) => { | ||
acc[item.key] = item.className; | ||
|
||
return acc; | ||
}, {}), | ||
})); | ||
setElementRules(elementsStyleData.map((el) => el.rule)); | ||
}); | ||
|
||
//add rules to style element | ||
createEffect(() => { | ||
const styleEl = styleElement(); | ||
if (!styleEl) { | ||
return; | ||
} | ||
|
||
styleEl.innerHTML = [...variableRules(), ...elementRules()].join(' '); | ||
}); | ||
|
||
return ( | ||
<AppearanceContext.Provider | ||
value={{ | ||
elements: props.elements || {}, | ||
descriptorToCssInJsClass: store.descriptorToCssInJsClass, | ||
}} | ||
> | ||
{props.children} | ||
</AppearanceContext.Provider> | ||
); | ||
}; | ||
|
||
export function useAppearance() { | ||
const context = useContext(AppearanceContext); | ||
if (!context) { | ||
throw new Error('useAppearance must be used within an AppearanceProvider'); | ||
} | ||
|
||
return context; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './AppearanceContext'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './use-style'; | ||
export * from './utils'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { createMemo, createSignal, onMount } from 'solid-js'; | ||
import { Elements, useAppearance } from '../context'; | ||
import { cn } from './utils'; | ||
|
||
export const useStyle = () => { | ||
const appearance = useAppearance(); | ||
const [isServer, setIsServer] = createSignal(true); | ||
|
||
onMount(() => { | ||
setIsServer(false); | ||
}); | ||
|
||
const styleFuncMemo = createMemo(() => (className: string, descriptor?: keyof Elements | keyof Elements[]) => { | ||
const appearanceClassname = | ||
descriptor && typeof appearance.elements?.[descriptor] === 'string' | ||
? (appearance.elements?.[descriptor] as string) || '' | ||
: ''; | ||
|
||
const descriptors = (Array.isArray(descriptor) ? descriptor : [descriptor]).map((des) => `nv-${des}`); | ||
const cssInJsClasses = | ||
!!descriptors.length && !isServer() ? descriptors.map((des) => appearance.descriptorToCssInJsClass[des]) : []; | ||
|
||
return cn( | ||
...descriptors, | ||
className, // default styles | ||
appearanceClassname, // overrides via appearance prop classes | ||
...cssInJsClasses | ||
); | ||
}); | ||
|
||
return styleFuncMemo(); | ||
}; |
Oops, something went wrong.