Skip to content

Commit

Permalink
Merge branch 'release/3.1.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
shannonhochkins committed Dec 8, 2023
2 parents 56b2776 + af83192 commit ee1ff4c
Show file tree
Hide file tree
Showing 46 changed files with 2,930 additions and 791 deletions.
2 changes: 1 addition & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default ({
if (prop.name === 'cssStyles' || prop.name === 'style') {
return true;
}
const res = /react-thermostat/.test(prop.parent?.fileName) || !/node_modules/.test(prop.parent?.fileName);
const res = !/node_modules/.test(prop.parent?.fileName);
return prop.parent ? res : true;
},
shouldExtractLiteralValuesFromEnum: true,
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@

# 3.1.1
## @hakit/components
- NEW - ClimateCard - completely rebuilt to match home assistant controls, as the original climate control was far too primitive, it supports everything the current climate card supports in home assistant. (Goodbye react-thermostat, sorry old shannon but it's just not good enough)
- NEW - ThemeProvider now accepts global styles for most cards, this is useful if you want to update the style globally for every instance of the same component, ie, change all modal backgrounds to red for example.
- NEW - Menu - a simple shared component that allows you to wrap any component and turn it into a clickable item that launches a menu
- NEW - ControlSliderCircular - a new shared component similar to the home assistant slider used for climate / humidity entities
- NEW - Modal animation changes - contents of the modal are now rendered after the modal animation has complete, which will then trigger the modal to animate
the children into the view.

## @hakit/core
- BUGFIX - useAreas - was previously returning a deviceEntities property - this has now been removed as it was showing literally every available device on the instance.
- UPGRADE - home assistant web socket - upgraded to match new types

# 3.1.0
Upgrading all packages, leaving CJS stack trace in place so we can monitor updates of packages that haven't been upgraded to ESM only yet, type fixes
## @hakit/components
- No code changes aside from base package upgrades
Expand Down
3 changes: 3 additions & 0 deletions hass-connect-fake/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const fakeConfig: HassConfig = {
"version": "2023.8.2",
"config_source": "storage",
"safe_mode": false,
"recovery_mode": false,
"state": "RUNNING",
"external_url": null,
"internal_url": null,
Expand Down Expand Up @@ -248,6 +249,8 @@ const useStore = create<Store>((set) => ({
...breakpoints,
xlg: breakpoints.lg + 1,
} }),
globalComponentStyles: {},
setGlobalComponentStyles: (globalComponentStyles) => set({ globalComponentStyles }),
}))

function HassProvider({
Expand Down
43 changes: 11 additions & 32 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 6 additions & 7 deletions packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@hakit/components",
"type": "module",
"version": "3.1.0",
"version": "3.1.1",
"private": false,
"keywords": [
"react",
Expand Down Expand Up @@ -65,10 +65,10 @@
"test": "NODE_ENV=test jest --rootDir=src"
},
"peerDependencies": {
"@emotion/react": ">=10.x",
"@emotion/styled": ">=10.x",
"@emotion/react": ">=11.x",
"@emotion/styled": ">=11.x",
"@fullcalendar/react": ">=6.x.x",
"@hakit/core": "^3.0.5",
"@hakit/core": "^3.1.1",
"@use-gesture/react": ">=10.x",
"autolinker": ">=4.x",
"framer-motion": ">=10.x",
Expand All @@ -79,10 +79,9 @@
"react-dom": ">=16.x",
"react-error-boundary": "^4.x",
"react-resize-detector": ">=9.x.x",
"react-thermostat": "^2.x.x",
"react-use": ">=17.x",
"use-long-press": ">=3.x.x",
"use-debounce": ">=9.x"
"use-debounce": ">=9.x",
"use-long-press": ">=3.x.x"
},
"devDependencies": {
"@emotion/babel-plugin": "^11.x",
Expand Down
8 changes: 7 additions & 1 deletion packages/components/src/Cards/AreaCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,13 @@ function _AreaCard({
onClick,
disable,
id,
cssStyles,
...rest
}: AreaCardProps) {
const _id = useId();
const idRef = id ?? _id;
const { addRoute, getRoute } = useHass();
const { useStore, addRoute, getRoute } = useHass();
const globalComponentStyle = useStore((state) => state.globalComponentStyles);
const [isPressed] = useKeyPress((event) => event.key === "Escape");
const [open, setOpen] = useState(false);
const route = useMemo(() => getRoute(hash), [hash, getRoute]);
Expand Down Expand Up @@ -229,6 +231,10 @@ function _AreaCard({
}
}
}}
cssStyles={`
${globalComponentStyle.areaCard ?? ""}
${cssStyles ?? ""}
`}
{...rest}
>
<PreloadImage
Expand Down
9 changes: 8 additions & 1 deletion packages/components/src/Cards/ButtonCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useMemo } from "react";
import styled from "@emotion/styled";
import { lowerCase, startCase } from "lodash";
import type { EntityName } from "@hakit/core";
import { useEntity, useIconByDomain, useIcon, useIconByEntity, isUnavailableState, ON } from "@hakit/core";
import { useEntity, useHass, useIconByDomain, useIcon, useIconByEntity, isUnavailableState, ON } from "@hakit/core";
import { fallback, Column, CardBase, type CardBaseProps, type AvailableQueries } from "@components";
import { computeDomain } from "@utils/computeDomain";
import { ErrorBoundary } from "react-error-boundary";
Expand Down Expand Up @@ -189,8 +189,11 @@ function _ButtonCard<E extends EntityName>({
hideLastUpdated,
children,
hideDetails,
cssStyles,
...rest
}: ButtonCardProps<E>): JSX.Element {
const { useStore } = useHass();
const globalComponentStyle = useStore((state) => state.globalComponentStyles);
const domain = _entity ? computeDomain(_entity) : null;
const entity = useEntity(_entity || "unknown", {
returnNullIfNotFound: true,
Expand Down Expand Up @@ -245,6 +248,10 @@ function _ButtonCard<E extends EntityName>({
disabled={disabled || isUnavailable}
onClick={onClick}
className={`${className ?? ""} ${defaultLayout ?? "default"} button-card`}
cssStyles={`
${globalComponentStyle.buttonCard ?? ""}
${cssStyles ?? ""}
`}
{...rest}
>
<Contents>
Expand Down
7 changes: 6 additions & 1 deletion packages/components/src/Cards/CalendarCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,9 @@ const defaultFullCalendarConfig: CalendarOptions = {
},
};

function _CalendarCard({ entities, className, timeZone, view, includeHeader = true, ...rest }: CalendarCardProps): JSX.Element {
function _CalendarCard({ entities, className, timeZone, view, includeHeader = true, cssStyles, ...rest }: CalendarCardProps): JSX.Element {
const { useStore } = useHass();
const globalComponentStyle = useStore((state) => state.globalComponentStyles);
const config = useStore((store) => store.config);
const calRef = useRef<FullCalendar>(null);
const initialRequest = useRef(false);
Expand Down Expand Up @@ -592,6 +593,10 @@ function _CalendarCard({ entities, className, timeZone, view, includeHeader = tr
disableActiveState
disableRipples
className={`calendar-card ${className ?? ""} ${narrow ? "narrow" : ""}`}
cssStyles={`
${globalComponentStyle.calendarCard ?? ""}
${cssStyles ?? ""}
`}
{...rest}
>
{includeHeader && (
Expand Down
9 changes: 8 additions & 1 deletion packages/components/src/Cards/CameraCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { EntityName, FilterByDomain, CameraEntityExtended } from "@hakit/core";
import { useCamera, isUnavailableState, STREAM_TYPE_WEB_RTC, STREAM_TYPE_HLS } from "@hakit/core";
import { useCamera, useHass, isUnavailableState, STREAM_TYPE_WEB_RTC, STREAM_TYPE_HLS } from "@hakit/core";
import styled from "@emotion/styled";
import { useEffect, useCallback, useRef, useState, useMemo, Children, isValidElement, cloneElement } from "react";
import {
Expand Down Expand Up @@ -127,8 +127,11 @@ function _CameraCard({
onClick,
service,
serviceData,
cssStyles,
...rest
}: CameraCardProps) {
const { useStore } = useHass();
const globalComponentStyle = useStore((state) => state.globalComponentStyles);
const cameraUpdater = useRef<number | undefined>(undefined);
const loadingIconRef = useRef<SVGSVGElement | null>(null);
const stateValueRef = useRef<HTMLDivElement | null>(null);
Expand Down Expand Up @@ -277,6 +280,10 @@ function _CameraCard({
onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
if (onClick) onClick(camera, event);
}}
cssStyles={`
${globalComponentStyle.cameraCard ?? ""}
${cssStyles ?? ""}
`}
{...rest}
>
<Header justifyContent="space-between" gap="0.5rem">
Expand Down
6 changes: 5 additions & 1 deletion packages/components/src/Cards/CardBase/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
computeDomain,
isUnavailableState,
useEntity,
useHass,
} from "@hakit/core";
import { CSSInterpolation } from "@emotion/serialize";
import {
Expand Down Expand Up @@ -210,6 +211,8 @@ const _CardBase = function _CardBase<T extends ElementType, E extends EntityName
...rest
}: CardBaseProps<T, E>) {
const _id = useId();
const { useStore } = useHass();
const globalComponentStyle = useStore((state) => state.globalComponentStyles);
const [openModal, setOpenModal] = useState(false);
const domain = _entity ? computeDomain(_entity) : null;
const entity = useEntity(_entity ?? "unknown", {
Expand Down Expand Up @@ -291,14 +294,15 @@ const _CardBase = function _CardBase<T extends ElementType, E extends EntityName
isUnavailable ? "unavailable" : ""
} ${disabled ? "disabled" : ""} `}
css={css`
${globalComponentStyle.cardBase ?? ""}
${cssStyles ?? ""}
`}
style={{
...(style ?? {}),
borderRadius: _borderRadius,
}}
whileTap={whileTap ?? { scale: disableScale || disabled || isUnavailable ? 1 : 0.9 }}
{...(typeof _entity === "string" ? bind() : {})}
{...bind()}
onClick={onClickHandler}
layoutId={layoutId ?? _id}
disableActiveState={disableActiveState}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { Meta, StoryObj, Args } from "@storybook/react";
import { ThemeProvider, ClimateCard } from "@components";
import { ThemeProvider, ClimateCard, Row } from "@components";
import { HassConnect } from "@hass-connect-fake";

function Render(args?: Args) {
return (
<HassConnect hassUrl="http://localhost:8123">
<ThemeProvider includeThemeControls />
<ClimateCard entity={"climate.air_conditioner"} {...args} />
<Row gap="2rem">
<ClimateCard entity={"climate.air_conditioner"} {...args} />
<ClimateCard hvacModes={["cool", "heat"]} entity={"climate.air_conditioner"} {...args} />
</Row>
</HassConnect>
);
}
Expand Down
12 changes: 9 additions & 3 deletions packages/components/src/Cards/ClimateCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,17 @@ function _ClimateCard({
onClick,
hvacModes,
hideCurrentTemperature,
hideFanMode,
hideHvacModes,
disabled,
className,
modalProps,
service,
serviceData,
cssStyles,
...rest
}: ClimateCardProps): JSX.Element {
const { getConfig } = useHass();
const { getConfig, useStore } = useHass();
const globalComponentStyle = useStore((state) => state.globalComponentStyles);
const entity = useEntity(_entity);
const entityIcon = useIconByEntity(_entity);
const domainIcon = useIconByDomain("climate");
Expand Down Expand Up @@ -132,12 +134,16 @@ function _ClimateCard({
...modalProps,
hvacModes: havacModesToUse,
hideCurrentTemperature,
hideFanMode,
hideHvacModes,
}}
onClick={() => {
if (isUnavailable || disabled || typeof onClick !== "function") return;
onClick(entity);
}}
cssStyles={`
${globalComponentStyle.climateCard ?? ""}
${cssStyles ?? ""}
`}
{...rest}
>
<Column
Expand Down
Loading

0 comments on commit ee1ff4c

Please sign in to comment.