Skip to content

Commit

Permalink
Refactor #4602 - Add unstyled feature
Browse files Browse the repository at this point in the history
  • Loading branch information
ulasturann committed Jul 4, 2023
1 parent 840d557 commit 7d7be62
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 5 deletions.
5 changes: 4 additions & 1 deletion components/lib/api/PrimeReactContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const PrimeReactProvider = (props) => {
toast: 1200
});
const [pt, setPt] = useState(undefined);
const [unstyled, setUnstyled] = useState(false);
const [filterMatchModeOptions, setFilterMatchModeOptions] = useState({
text: [FilterMatchMode.STARTS_WITH, FilterMatchMode.CONTAINS, FilterMatchMode.NOT_CONTAINS, FilterMatchMode.ENDS_WITH, FilterMatchMode.EQUALS, FilterMatchMode.NOT_EQUALS],
numeric: [FilterMatchMode.EQUALS, FilterMatchMode.NOT_EQUALS, FilterMatchMode.LESS_THAN, FilterMatchMode.LESS_THAN_OR_EQUAL_TO, FilterMatchMode.GREATER_THAN, FilterMatchMode.GREATER_THAN_OR_EQUAL_TO],
Expand Down Expand Up @@ -70,7 +71,9 @@ export const PrimeReactProvider = (props) => {
pt,
setPt,
filterMatchModeOptions,
setFilterMatchModeOptions
setFilterMatchModeOptions,
unstyled,
setUnstyled
};

return <PrimeReactContext.Provider value={value}>{props.children}</PrimeReactContext.Provider>;
Expand Down
1 change: 1 addition & 0 deletions components/lib/api/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ export interface APIOptions {
* This option allows to direct implementation of all relevant attributes (e.g., style, classnames) within the respective HTML tag.
*/
pt?: PrimeReactPTOptions;
unstyled?: boolean;
/**
* This method is used to change the theme dynamically.
* @param {string} theme - The name of the theme to be applied.
Expand Down
46 changes: 42 additions & 4 deletions components/lib/componentbase/ComponentBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,27 @@ import { ObjectUtils } from '../utils/Utils';

export const ComponentBase = {
defaultProps: {
pt: undefined
pt: undefined,
unstyled: false
},
context: undefined,
classes: {},
styles: "",
extend: (props = {}) => {
const css = props.css;
const defaultProps = { ...props.defaultProps, ...ComponentBase.defaultProps };
const inlineStyles = {
hiddenAccessible: {
border: '0',
clip: 'rect(0 0 0 0)',
height: '1px',
margin: '-1px',
overflow: 'hidden',
padding: '0',
position: 'absolute',
width: '1px'
}
};

const getProps = (props, context = {}) => {
ComponentBase.context = context;
Expand All @@ -29,7 +45,6 @@ export const ComponentBase = {
const datasetPrefix = 'data-pc-';
const componentName = (params.props && params.props.__TYPE && ObjectUtils.convertToFlatCase(params.props.__TYPE)) || '';
const pt = ComponentBase.context.pt || PrimeReact.pt || {};

const defaultPT = (key) => pt && getOptionValue(pt[componentName], key);
const self = ObjectUtils.getPropValue(obj, key, params)[key];
const globalPT = defaultPT(key);
Expand All @@ -53,10 +68,33 @@ export const ComponentBase = {
};

const setMetaData = (metadata = {}) => {
const ptm = (key = '', params = {}) => ptmo((metadata.props || {}).pt, key, { ...metadata, ...params });
const { props, state } = metadata;
const ptm = (key = '', params = {}) => ptmo((props || {}).pt, key, { ...metadata, ...params });
const ptmo = (obj = {}, key = '', params = {}) => getPTValue(obj, key, params);

return { ptm, ptmo };
const isUnstyled = () => {
return ComponentBase.context.unstyled || PrimeReact.unstyled || props.unstyled;
};

const cx = (key = '', params = {}) => {
return !isUnstyled() ? getOptionValue(css && css.classes, key, { props, state, ...params }) : undefined;
};

const sx = (key = '', when = true, params = {}) => {
if (when) {
const self = getOptionValue(css && css.inlineStyles, key, { props, state, ...params });
const base = getOptionValue(inlineStyles, key, { props: props || {}, state, ...params });
let merged = {
...ObjectUtils.getMergedProps(base, self)
};

return merged;
}

return undefined;
}

return { ptm, ptmo, sx, cx };
};

return {
Expand Down
2 changes: 2 additions & 0 deletions components/lib/hooks/Hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useLocalStorage, useSessionStorage, useStorage } from './useStorage';
import { useTimeout } from './useTimeout';
import { useUnmountEffect } from './useUnmountEffect';
import { useUpdateEffect } from './useUpdateEffect';
import { useStyle } from './useStyle';

export {
usePrevious,
Expand All @@ -30,6 +31,7 @@ export {
useIntersectionObserver,
useInterval,
useStorage,
useStyle,
useLocalStorage,
useSessionStorage,
useTimeout,
Expand Down
46 changes: 46 additions & 0 deletions components/lib/hooks/hooks.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,45 @@ interface MousePositionOptions {
y: number;
}

/**
* Custom UseStyleOptions
*/
interface UseStyleOptions {
document?: Document;
immediate: boolean;
manual: boolean;
name: string;
media: string;
}

/**
* Custom StyleOptions
*/
interface StyleOptions {
/**
* Defines data-pc-name attribute of the style tag.
*/
name: string;
/**
* The css object.
*/
css: React.RefObject<string>;
/**
* This option is used to load the style tag by the name.
* @returns {void}
*/
load: () => void;
/**
* This method is used to remove the style tag from the head.
* @returns {void}
*/
unload: () => void;
/**
* Whether the style is loaded or not.
*/
isLoaded: boolean;
}

/**
* Custom MouseDataOptions
*/
Expand Down Expand Up @@ -220,6 +259,13 @@ export declare function useMouse(): MouseDataOptions;
* @param {MousePositionOptions} initialValue - The initial value.
*/
export declare function useMove(mode: 'horizontal' | 'vertical' | 'both', initialValue: MousePositionOptions): MouseMoveOptions;

/**
* Custom hook to use to get style options.
* @param {string} css - The style text content.
* @param {UseStyleOptions} options - The options of the style.
*/
export declare function useStyle(css: string, options?: UseStyleOptions): StyleOptions;
/**
* Custom hook to use change the current favicon.
* @param {string} newIcon - The new favicon url to set.
Expand Down
59 changes: 59 additions & 0 deletions components/lib/hooks/useStyle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useEffect, useRef, useState } from 'react';
import { DomHandler, ObjectUtils } from "../utils/Utils";

let _id = 0;

export const useStyle = (css = {}, options = {}) => {
const [isLoaded, setIsLoaded] = useState(false);

const cssRef = useRef(null);
const defaultDocument = DomHandler.isClient() ? window.document : undefined;
const { document = defaultDocument, immediate = true, manual = false, name = `primereact_style_${++_id}`, media } = options;

useEffect(() => {
cssRef.current = css;
}, [css]);

const load = () => {
if (!document) return;

const el = document.querySelector(`[data-pc-name="${name}"]`) || document.createElement('style');

if (ObjectUtils.isNotEmpty(el) || !el.isConnected) {
el.type = 'text/css';
el.setAttribute('data-pc-name', name);
if (media) el.media = media;
document.head.appendChild(el);
}

if (isLoaded) return;

el.textContent = cssRef.current;
setIsLoaded(true);
};

const unload = () => {
if (!document || !isLoaded) return;
const node = document.querySelector(`[data-pc-name="${name}"]`);

if (node && node.isConnected) {
document.head.removeChild(node);
setIsLoaded(false);
}
};

useEffect(() => {
if (immediate && !manual) load();

return () => unload();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [immediate, manual]);

return {
name,
css: cssRef,
unload,
load,
isLoaded
};
}
4 changes: 4 additions & 0 deletions components/lib/utils/DomHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,10 @@ export default class DomHandler {
return /(chrome)/i.test(navigator.userAgent);
}

static isClient() {
return !!(typeof window !== 'undefined' && window.document && window.document.createElement);
}

static isTouchDevice() {
return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
}
Expand Down
1 change: 1 addition & 0 deletions components/lib/utils/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export declare class DomHandler {
static getUserAgent(): string;
static isIOS(): boolean;
static isAndroid(): boolean;
static isClient(): boolean;
static isTouchDevice(): boolean;
static isFunction(obj: any): boolean;
static appendChild(el: HTMLElement, target: HTMLElement): void;
Expand Down

0 comments on commit 7d7be62

Please sign in to comment.