lodash#isNumber TypeScript Examples

The following examples show how to use lodash#isNumber. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: analysis-utils.ts    From prism-frontend with MIT License 7 votes vote down vote up
function thresholdOrNaN(value: number, threshold?: ThresholdDefinition) {
  // filter out nullish values.
  if (!isNumber(value)) {
    return NaN;
  }

  // if there is no threshold, simply return the original value.
  if (threshold === undefined) {
    return value;
  }

  const isAbove =
    threshold.above === undefined ? true : value >= threshold.above;
  const isBelow =
    threshold.below === undefined ? true : value <= threshold.below;
  return isAbove && isBelow ? value : NaN;
}
Example #2
Source File: utils.tsx    From XFlow with MIT License 7 votes vote down vote up
createPath = (paths: (string | number)[][], offsetX = 0, offsetY = 0) => {
  if (!paths.length) {
    return null
  }
  let path = ''
  // @ts-ignore
  paths.forEach((item: IPath) => {
    const [c, x, y, c2x, c2y] = item
    path += isNumber(y) ? ` ${c} ${x + offsetX} ${y + offsetY}` : ` ${c}`
    if (c2y) {
      path += ` ${c2x + offsetX} ${c2y + offsetY}`
    }
  })

  return path
}
Example #3
Source File: utilities.ts    From react-native-jigsaw with MIT License 7 votes vote down vote up
export function getValueForRadioButton(value: string | number) {
  if (isString(value)) {
    return value;
  } else if (isNumber(value)) {
    return String(value);
  } else {
    throw new Error(`Invalid value: ${value}`);
  }
}
Example #4
Source File: index.tsx    From prism-frontend with MIT License 6 votes vote down vote up
DataTableRow = ({ className, columns, rowData }: TableRowProps) => {
  const { t } = useSafeTranslation();
  return (
    <TableRow>
      {columns.map(column => {
        const colValue = rowData ? rowData[column] : column;
        const formattedColValue = isNumber(colValue)
          ? getRoundedData(colValue, t)
          : t(colValue).toLocaleString();
        return (
          <TableCell className={className} key={column}>
            {' '}
            {formattedColValue}{' '}
          </TableCell>
        );
      })}
    </TableRow>
  );
}
Example #5
Source File: bleachingAlert.ts    From aqualink-app with MIT License 6 votes vote down vote up
calculateAlertLevel = (
  maxMonthlyMean?: number | null,
  satelliteTemperature?: number | null,
  degreeHeatingDays?: number | null,
): number | undefined => {
  const hotSpot =
    satelliteTemperature &&
    maxMonthlyMean &&
    satelliteTemperature - maxMonthlyMean;

  switch (true) {
    case isNil(hotSpot):
      return undefined;

    case isNumber(hotSpot) && hotSpot <= 0:
      return 0;

    case isNumber(hotSpot) && hotSpot < 1:
      return 1;

    // Hotspot >=1 or nil past this point, start dhw checks.
    case isNil(degreeHeatingDays):
      return 0;

    case inRange(degreeHeatingDays!, 0, 4 * 7):
      return 2;

    case inRange(degreeHeatingDays!, 4 * 7, 8 * 7):
      return 3;

    case degreeHeatingDays! >= 8 * 7:
      return 4;

    default:
      return undefined;
  }
}
Example #6
Source File: StarBadge.tsx    From hub with Apache License 2.0 6 votes vote down vote up
StarBadge = (props: Props) => {
  if (isUndefined(props.starsNumber) || !isNumber(props.starsNumber)) return null;
  return (
    <div
      data-testid="starBadge"
      className={classnames('badge rounded-pill bg-light text-dark border', styles.badge, props.className, {
        [styles[`size-${props.size}`]]: !isUndefined(props.size),
      })}
      aria-label={`${props.starsNumber} stars`}
    >
      <div className="d-flex align-items-center">
        <FaStar className={`me-1 ${styles.icon}`} />
        <div>{prettifyNumber(props.starsNumber)}</div>
      </div>
    </div>
  );
}
Example #7
Source File: records.ts    From ts-di-starter with MIT License 6 votes vote down vote up
/**
   * Patch record
   *
   * @param {Request} request
   * @returns {Promise<Record>}
   */
  async patch(request): Promise<Record> {
    assertProperties(request.locals, ['user']);
    const { user }: { user: UserModel } = request.locals;
    assertProperties(request.params, ['recordId']);
    const { recordId }: { recordId: string } = request.params;

    const { value } = request.body;

    if (!isNumber(value)) {
      throw new Err('value must be a number', HTTP_STATUS.BAD_REQUEST);
    }

    await this.services.records.assertUserRecord(recordId, user.id);

    return this.services.records.patch(recordId, value);
  }
Example #8
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 6 votes vote down vote up
TimeSpanFilterItem = ({
  itemData,
  value,
  active,
  onVisibleChange,
  onChange,
  onQuickOperation,
  labels,
}: Merge<IFilterItemProps<'timespanRange'>, { labels: JSX.Element }>) => {
  const [duration, setDuration] = React.useState();
  useEffectOnce(() => {
    setDuration(value);
  });

  const { key, label, placeholder, disabled } = itemData;
  return (
    <span className="contractive-filter-item">
      {labels}
      <Duration
        value={duration}
        onChange={(v) => {
          const durationMin = transformDuration(v?.[0]);
          const durationMax = transformDuration(v?.[1]);
          if (isNumber(durationMin) && isNumber(durationMax)) {
            if (durationMin <= durationMax) {
              onChange({ key, value: v });
            } else {
              message.error(i18n.t('msp:wrong duration'));
            }
          } else if (!isNumber(durationMin) && !isNumber(durationMax)) {
            onChange({ key, value: [] });
          }
        }}
      />
    </span>
  );
}
Example #9
Source File: add-edit-mileage.page.ts    From fyle-mobile-app with MIT License 6 votes vote down vote up
addToNewReport(txnId: string) {
    const that = this;
    from(this.loaderService.showLoader())
      .pipe(
        switchMap(() => this.transactionService.getEtxn(txnId)),
        finalize(() => from(this.loaderService.hideLoader()))
      )
      .subscribe((etxn) => {
        const criticalPolicyViolated = isNumber(etxn.tx_policy_amount) && etxn.tx_policy_amount < 0.0001;
        if (!criticalPolicyViolated) {
          that.router.navigate(['/', 'enterprise', 'my_create_report', { txn_ids: JSON.stringify([txnId]) }]);
        } else {
          that.close();
        }
      });
  }
Example #10
Source File: InputNumber.tsx    From gant-design with MIT License 6 votes vote down vote up
withInputNumber = compose(
  withProps(({ value, onChange, format }) => {
    let $value = value;
    const notnumber = value && !isNumber(value);
    if (notnumber) {
      $value = null
    }
    if (!isNil($value)) {
      $value = numeral($value).value()
    }

    return {
      value: $value,
      onChange: (val) => {
        let numberVal = val;
        if (format) {
          numberVal = Number(numeral(numberVal).format(format));
        }
        onChange && onChange(numberVal);
      }
    }
  })
)
Example #11
Source File: update-one-user-search-group.ts    From js-client with MIT License 6 votes vote down vote up
makeUpdateOneUserSearchGroup = (context: APIContext) => {
	return async (userID: NumericID, groupID: NumericID | null): Promise<void> => {
		try {
			const path = '/api/users/{userID}/searchgroup';
			const url = buildURL(path, { ...context, protocol: 'http', pathParams: { userID } });

			const body: UpdateOneUserSearchGroupRawRequest = {
				GID: isNumber(groupID) ? groupID : isNull(groupID) ? groupID : parseInt(groupID, 10),
			};

			const baseRequestOptions: HTTPRequestOptions = {
				body: JSON.stringify(body),
			};
			const req = buildHTTPRequestWithAuthFromContext(context, baseRequestOptions);

			const raw = await context.fetch(url, { ...req, method: 'PUT' });
			return parseJSONResponse(raw, { expect: 'void' });
		} catch (err) {
			if (err instanceof Error) throw err;
			throw Error('Unknown error');
		}
	};
}
Example #12
Source File: useValue.ts    From gio-design with Apache License 2.0 6 votes vote down vote up
formatValue = (isMultiple: boolean, value?: MaybeArray<string | number>) => {
  if (isMultiple) {
    if (isNil(value)) {
      return [];
    }
    if (isString(value) || isNumber(value)) {
      return [value];
    }
    return value;
  }
  if (isNil(value)) {
    return '';
  }
  return value;
}
Example #13
Source File: helpers.tsx    From leda with MIT License 6 votes vote down vote up
getNumericValue = (val?: number | string | undefined): number | null => {
  if (!isNil(val)) {
    if (isNumber(val)) return val;

    const parsedValue = parseFloat(val.replace(/\s/g, '')); // убрать все пробелы из строки

    return Number.isNaN(parsedValue) ? null : parsedValue;
  }

  return null;
}
Example #14
Source File: helpers.ts    From querybook with Apache License 2.0 6 votes vote down vote up
export function detectVariableType(value: any): TSupportedTypes {
    if (isBoolean(value)) {
        return 'boolean';
    }
    if (isNumber(value)) {
        return 'number';
    }
    return 'string';
}
Example #15
Source File: balance.ts    From subscan-multisig-react with Apache License 2.0 6 votes vote down vote up
toString = (value: string | BN | number): string => {
  if (BN.isBN(value)) {
    return value.toString();
  } else if (isString(value)) {
    return Number(value).toString(10);
  } else if (isNumber(value)) {
    return value.toString(10);
  } else if (isUndefined(value) || isNaN(value) || isNull(value)) {
    return '0';
  } else {
    throw new TypeError(
      // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
      `Can not convert the value ${value} to String type. Value type is ${typeof value}`
    );
  }
}
Example #16
Source File: processDataFrame.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
/**
 * Given a value this will guess the best column type
 *
 * TODO: better Date/Time support!  Look for standard date strings?
 */
export function guessFieldTypeFromValue(v: any): FieldType {
  if (isNumber(v)) {
    return FieldType.number;
  }

  if (isString(v)) {
    if (NUMBER.test(v)) {
      return FieldType.number;
    }

    if (v === 'true' || v === 'TRUE' || v === 'True' || v === 'false' || v === 'FALSE' || v === 'False') {
      return FieldType.boolean;
    }

    return FieldType.string;
  }

  if (isBoolean(v)) {
    return FieldType.boolean;
  }

  if (v instanceof Date || isDateTime(v)) {
    return FieldType.time;
  }

  return FieldType.other;
}
Example #17
Source File: Kernel.ts    From GWebGPUEngine with MIT License 5 votes vote down vote up
public setBinding(
    name:
      | string
      | Record<
          string,
          | number
          | number[]
          | Float32Array
          | Uint8Array
          | Uint16Array
          | Uint32Array
          | Int8Array
          | Int16Array
          | Int32Array
        >,
    data?:
      | number
      | number[]
      | Float32Array
      | Uint8Array
      | Uint16Array
      | Uint32Array
      | Int8Array
      | Int16Array
      | Int32Array
      | Kernel,
  ) {
    if (typeof name === 'string') {
      const isNumberLikeData =
        isNumber(data) || isTypedArray(data) || isArray(data);
      if (this.compiledBundle && this.compiledBundle.context) {
        // set define, eg. setBinding('MAX_LENGTH', 10)
        const existedDefine = this.compiledBundle.context.defines.find(
          (b) => b.name === name,
        );
        if (existedDefine) {
          existedDefine.value = data as number;
          return this;
        }

        // set uniform
        const existedBinding = this.compiledBundle.context.uniforms.find(
          (b) => b.name === name,
        );
        if (existedBinding) {
          // update uniform or buffer
          if (isNumberLikeData) {
            // @ts-ignore
            existedBinding.data = data;
            existedBinding.isReferer = false;

            if (existedBinding.storageClass === STORAGE_CLASS.Uniform) {
              if (this.model) {
                // @ts-ignore
                this.model.updateUniform(name, data);
              }
            } else {
              if (this.model) {
                // @ts-ignore
                this.model.updateBuffer(name, data);
              }
            }
          } else {
            // update with another kernel
            existedBinding.isReferer = true;
            // @ts-ignore
            existedBinding.data = data as Kernel;
          }
        }
      }
    } else {
      Object.keys(name).forEach((key) => {
        this.setBinding(key, name[key]);
      });
    }
    return this;
  }
Example #18
Source File: base-cell.ts    From S2 with MIT License 5 votes vote down vote up
// 根据当前state来更新cell的样式
  public updateByState(stateName: InteractionStateName, cell: S2CellType) {
    this.spreadsheet.interaction.setInteractedCells(cell);
    const stateStyles = get(
      this.theme,
      `${this.cellType}.cell.interactionState.${stateName}`,
    );

    const { x, y, height, width } = this.getCellArea();

    each(stateStyles, (style, styleKey) => {
      const targetShapeNames = keys(
        pickBy(SHAPE_ATTRS_MAP, (attrs) => includes(attrs, styleKey)),
      );
      targetShapeNames.forEach((shapeName: StateShapeLayer) => {
        const isStateShape = this.stateShapes.has(shapeName);
        const shape = isStateShape
          ? this.stateShapes.get(shapeName)
          : this[shapeName];

        // stateShape 默认 visible 为 false
        if (isStateShape && !shape.get('visible')) {
          shape.set('visible', true);
        }

        // 根据borderWidth更新borderShape大小 https://github.com/antvis/S2/pull/705
        if (
          shapeName === 'interactiveBorderShape' &&
          styleKey === 'borderWidth'
        ) {
          if (isNumber(style)) {
            const marginStyle = {
              x: x + style / 2,
              y: y + style / 2,
              width: width - style - 1,
              height: height - style - 1,
            };
            each(marginStyle, (currentStyle, currentStyleKey) => {
              updateShapeAttr(shape, currentStyleKey, currentStyle);
            });
          }
        }
        updateShapeAttr(shape, SHAPE_STYLE_MAP[styleKey], style);
      });
    });
  }
Example #19
Source File: dailyData.ts    From aqualink-app with MIT License 5 votes vote down vote up
export function getMaxAlert(
  dailyAlertLevel?: number,
  weeklyAlertLevel?: number,
) {
  return getMax([weeklyAlertLevel, dailyAlertLevel].filter(isNumber));
}
Example #20
Source File: TemplateEngineManager.tsx    From easy-email with MIT License 5 votes vote down vote up
function generateConditionTemplate(
  option: NonNullable<AdvancedBlock['data']['value']['condition']>,
  content: React.ReactElement
) {
  const { symbol, groups } = option;

  const generateExpression = (condition: {
    left: string | number;
    operator: Operator;
    right: string | number;
  }) => {
    if (condition.operator === Operator.TRUTHY) {
      return condition.left;
    }
    if (condition.operator === Operator.FALSY) {
      return condition.left + ' == nil';
    }
    return (
      condition.left +
      ' ' +
      condition.operator +
      ' ' +
      (isNumber(condition.right) ? condition.right : `"${condition.right}"`)
    );
  };
  const uuid = nanoid(5);
  const variables = groups.map((_, index) => `con_${index}_${uuid}`);

  const assignExpression = groups
    .map((item, index) => {
      return `{% assign ${variables[index]} = ${item.groups
        .map(generateExpression)
        .join(` ${item.symbol} `)} %}`;
    })
    .join('\n');
  const conditionExpression = variables.join(` ${symbol} `);

  return (
    <Template>
      <Raw>
        {`
        <!-- htmlmin:ignore -->
        ${assignExpression}
        {% if ${conditionExpression} %}
        <!-- htmlmin:ignore -->
        `}
      </Raw>
      {content}
      <Raw>
        {`
        <!-- htmlmin:ignore -->
        {% endif %}
        <!-- htmlmin:ignore -->
        `}
      </Raw>
    </Template>
  );
}
Example #21
Source File: ElasticSearchSearchEngine.ts    From backstage with Apache License 2.0 5 votes vote down vote up
function isBlank(str: string) {
  return (isEmpty(str) && !isNumber(str)) || nan(str);
}
Example #22
Source File: NumberInput.tsx    From react-native-jigsaw with MIT License 5 votes vote down vote up
NumberInput: FC<Props> = ({
  onChangeText,
  value,
  defaultValue,
  ...props
}) => {
  const [currentStringNumberValue, setCurrentStringNumberValue] = useState("0");

  const formatValueToStringNumber = (valueToFormat?: number | string) => {
    if (valueToFormat != null) {
      if (isString(valueToFormat) && valueToFormat !== "") {
        if (/^0[1-9]$/.test(valueToFormat)) {
          return valueToFormat.slice(1);
        } else if (/^[+-]?([0-9]+\.?[0-9]*|\.[0-9]+)$/.test(valueToFormat)) {
          return valueToFormat;
        } else {
          return currentStringNumberValue;
        }
      } else if (isNumber(valueToFormat) && !isNaN(valueToFormat)) {
        return valueToFormat.toString();
      }
    }

    return "0";
  };

  // set currentStringNumberValue as defaultValue prop if there is a differnce on first render only
  useEffect(() => {
    const defaultStringNumberValue = formatValueToStringNumber(defaultValue);

    if (currentStringNumberValue !== defaultStringNumberValue) {
      setCurrentStringNumberValue(defaultStringNumberValue);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handleChangeText = (newValue: string) => {
    const newStringNumberValue = formatValueToStringNumber(newValue);
    const number = parseFloat(newStringNumberValue);

    setCurrentStringNumberValue(newStringNumberValue);
    onChangeText?.(number);
  };

  // run handleChangeText with value prop only when value prop changes (and first render to reset currentStringNumberValue)
  useEffect(() => {
    const nextStringNumberValue = formatValueToStringNumber(value);

    if (currentStringNumberValue !== nextStringNumberValue) {
      handleChangeText(nextStringNumberValue);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [value]);

  return (
    <TextInput
      keyboardType="numeric"
      value={currentStringNumberValue}
      onChangeText={handleChangeText}
      {...props}
    />
  );
}
Example #23
Source File: pipeline-node.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
private renderIcon() {
    const { isType, status, result, costTimeSec } = this.props.item.data;

    const operations = [];
    // if (!starting) {
    // 右侧图标:analysis config
    // if (isType('dice')) {
    //   operations.push(this.getIconOperation('link', 'config-link', '配置中心'));
    // }
    // }

    // 右侧跳转链接图标
    if (status === 'Success') {
      if (isType('it') || isType('ut')) {
        operations.push(this.getIconOperation('link', 'test-link', i18n.t('test')));
      }
      // if (name === 'sonar') {
      //   operations.push(this.getIconOperation('link', 'sonar-link', '代码质量'));
      // }
    }

    if (result) {
      const { metadata } = result;
      if (metadata != null) {
        const runtimeID = metadata.find((a: any) => a.name === 'runtimeID');
        if (runtimeID) {
          operations.push(this.getIconOperation('link', 'link', i18n.t('Overview')));
        }
        const releaseID = metadata.find((a: any) => a.name === 'releaseID');
        if (releaseID) {
          operations.push(this.getIconOperation('link', 'release-link', i18n.t('dop:version details')));
        }
        const publisherID = metadata.find((a: any) => a.name === 'publisherID');
        if (publisherID) {
          operations.push(this.getIconOperation('link', 'publisher-link', i18n.t('publisher:publisher content')));
        }
      }
    }

    if (status === 'Running' || (executeStatus.includes(status) && isNumber(costTimeSec) && costTimeSec !== -1)) {
      operations.push(this.getIconOperation('log', 'log', i18n.t('log')));
    }

    return operations.map((i: any, index: number) => (
      <React.Fragment key={`operation-${String(index)}`}>{i}</React.Fragment>
    ));
  }
Example #24
Source File: resubmit-report-popover.component.ts    From fyle-mobile-app with MIT License 5 votes vote down vote up
filterCriticalViolations(etxn) {
    return etxn.tx_policy_flag && isNumber(etxn.tx_policy_amount) && etxn.tx_policy_amount < 0.0001;
  }
Example #25
Source File: InputMoney.tsx    From gant-design with MIT License 5 votes vote down vote up
@compose(
  withMoneyType,
  withEdit(({ currency, money, format }) => {
    if (!isNumber(money)) return null
    const num = numeral(money).format(format)
    return `${currency} ${num}`
  }, "gantd-input-money-addonBefore"),
  withProps(({ currency, onCurrencyChange, size }) => {
    return ({
      addonBefore: (
        <Select dropdownClassName="gantd-input-money-addonBefore" className="gant-input-money-select" style={{ width: 75 }} value={currency}
          size={size}
          onChange={onCurrencyChange}>
          {
            symbols.map(type => <Select.Option key={type} value={type}>{type}</Select.Option>)
          }
        </Select>
      ),

    })
  }),
)
class InputMoney extends Component<any>{

  state = {
    value: undefined
  }

  constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this)
  }

  onChange(v) {
    const { reg, onMoneyChange } = this.props
    let value = String(numeral(v).value()) // 通过numeral去掉非数字
    const match = value.match(reg) // 最多两位小数
    if (match && match[0]) {
      value = match[0]
    }
    value = numeral(value).value() // 转化成数字
    this.setState({
      value
    })
    onMoneyChange(value)
  }

  render() {
    const { setType, onEnter, wrapperRef, onValueChange, precision, format, reg, addonBefore, ...props } = this.props
    const { value } = this.state

    return (
      <span className='gant-input-moeny'>
        {addonBefore}
        <InputNumber  {...props} ref={wrapperRef} wrapperClassName={'gant-input-moeny-number'} isInner value={props.money || value} min={0} edit={EditStatus.EDIT} onPressEnter={onEnter} onChange={this.onChange} />
      </span>
    );
  }
}
Example #26
Source File: is-dashboard-live-update.ts    From js-client with MIT License 5 votes vote down vote up
isDashboardLiveUpdate = (value: unknown): value is DashboardLiveUpdate => {
	try {
		const d = <DashboardLiveUpdate>value;
		return (d.enabled === true && isNumber(d.interval)) || (d.enabled === false && isNil(d.interval));
	} catch {
		return false;
	}
}
Example #27
Source File: Col.tsx    From gio-design with Apache License 2.0 5 votes vote down vote up
Col = ({
  component: Component = 'div',
  prefixCls: customizePrefixCls,
  children,
  className,
  style,
  order,
  offset,
  span = 1,
}: React.PropsWithChildren<ColProps>) => {
  const prefixCls = usePrefixCls('col', customizePrefixCls);
  const { gutters } = useContext(RowContext);

  const mergedStyle: React.CSSProperties = {
    ...(gutters[0] > 0
      ? {
          paddingLeft: gutters[0] / 2,
          paddingRight: gutters[0] / 2,
        }
      : {}),
    ...(gutters[1] > 0
      ? {
          paddingTop: gutters[1] / 2,
          paddingBottom: gutters[1] / 2,
        }
      : {}),
    ...style,
  };

  return (
    <Component
      className={classNames(prefixCls, className, `${prefixCls}-span-${span}`, {
        [`${prefixCls}-order-${order}`]: isNumber(order),
        [`${prefixCls}-offset-${offset}`]: isNumber(offset),
      })}
      style={mergedStyle}
    >
      {children}
    </Component>
  );
}
Example #28
Source File: Currency.tsx    From leda with MIT License 5 votes vote down vote up
Currency = React.forwardRef((props: CurrencyProps, ref?: React.Ref<CurrencyRefCurrent>) => {
  const {
    children,
    currencyCode = 'RUB',
    currencySymbolRender,
    placeholder: placeholderProp,
    shouldTrimFraction,
    precision,
    value: valueProp,
    wrapperRender,
    ...restProps
  } = props;

  const value = isNumber(valueProp) || isString(valueProp) ? valueProp : children;

  const numericValue = getNumericValue(value);

  const context = React.useContext(LedaContext);

  const CurrencySymbol = useElement<CurrencyProps, {}, CurrencySymbolProps>(
    'CurrencySymbol',
    Span,
    currencySymbolRender || context.renders[COMPONENTS_NAMESPACES.currency].currencySymbolRender,
    props,
  );

  const Wrapper = useElement(
    'Wrapper',
    Span,
    wrapperRender || context.renders[COMPONENTS_NAMESPACES.currency].wrapperRender,
    props,
  );

  const formattedValue = formatNumber(CurrencySymbol, numericValue, precision, currencyCode, shouldTrimFraction);

  const placeholder = isString(placeholderProp)
    ? placeholderProp
    : '—';

  return (
    <Wrapper
      ref={ref && ((component) => bindFunctionalRef(component, ref, component && {
        wrapper: component.wrapper,
      }))}
      {...restProps}
    >
      {numericValue === null
        ? placeholder
        : formattedValue}
    </Wrapper>
  );
}) as React.FC<CurrencyProps>
Example #29
Source File: WebGPUComputeModel.ts    From GWebGPUEngine with MIT License 4 votes vote down vote up
public async init() {
    const { computeStage } = await this.compileComputePipelineStageDescriptor(
      this.context.shader!,
    );

    const buffers = this.context.uniforms.filter(
      (uniform) => uniform.storageClass === STORAGE_CLASS.StorageBuffer,
    );
    const uniforms = this.context.uniforms.filter(
      (uniform) => uniform.storageClass === STORAGE_CLASS.Uniform,
    );

    let bufferBindingIndex = uniforms.length ? 1 : 0;
    this.bindGroupEntries = [];
    if (bufferBindingIndex) {
      let offset = 0;
      // FIXME: 所有 uniform 合并成一个 buffer,固定使用 Float32Array 存储,确实会造成一些内存的浪费
      // we use std140 layout @see https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)
      const mergedUniformData: number[] = [];
      uniforms.forEach((uniform) => {
        if (isNumber(uniform.data)) {
          this.uniformGPUBufferLayout.push({
            name: uniform.name,
            offset,
          });
          offset += 4;
          mergedUniformData.push(uniform.data);
        } else {
          let originDataLength = uniform.data?.length || 1;
          if (originDataLength === 3) {
            // vec3 -> vec4
            // @see http://ptgmedia.pearsoncmg.com/images/9780321552624/downloads/0321552628_AppL.pdf
            originDataLength = 4;
            uniform.data.push(0);
          }
          // 4 elements per block/line
          const padding = (offset / 4) % 4;
          if (padding > 0) {
            const space = 4 - padding;
            if (originDataLength > 1 && originDataLength <= space) {
              if (originDataLength === 2) {
                if (space === 3) {
                  offset += 4;
                  mergedUniformData.push(0);
                }
                mergedUniformData.push(...uniform.data);
                this.uniformGPUBufferLayout.push({
                  name: uniform.name,
                  offset,
                });
              }
            } else {
              for (let i = 0; i < space; i++) {
                offset += 4;
                mergedUniformData.push(0);
              }
              mergedUniformData.push(...uniform.data);
              this.uniformGPUBufferLayout.push({
                name: uniform.name,
                offset,
              });
            }
          }

          offset += 4 * originDataLength;
        }
      });

      this.uniformBuffer = new WebGPUBuffer(this.engine, {
        // TODO: 处理 Struct 和 boolean
        // @ts-ignore
        data:
          mergedUniformData instanceof Array
            ? // @ts-ignore
              new Float32Array(mergedUniformData)
            : mergedUniformData,
        usage:
          WebGPUConstants.BufferUsage.Uniform |
          WebGPUConstants.BufferUsage.CopyDst,
      });

      this.bindGroupEntries.push({
        binding: 0,
        resource: {
          buffer: this.uniformBuffer.get(),
        },
      });
    }

    // create GPUBuffers for storeage buffers
    buffers.forEach((buffer) => {
      if (!isNil(buffer.data)) {
        if (
          buffer.type === AST_TOKEN_TYPES.Vector4FloatArray ||
          buffer.type === AST_TOKEN_TYPES.FloatArray
        ) {
          let gpuBuffer;
          if (buffer.name === this.context.output.name) {
            gpuBuffer = new WebGPUBuffer(this.engine, {
              // @ts-ignore
              data: isFinite(Number(buffer.data)) ? [buffer.data] : buffer.data,
              usage:
                WebGPUConstants.BufferUsage.Storage |
                WebGPUConstants.BufferUsage.CopyDst |
                WebGPUConstants.BufferUsage.CopySrc,
            });
            this.outputBuffer = gpuBuffer;
            this.context.output = {
              name: buffer.name,
              // @ts-ignore
              length: isFinite(Number(buffer.data)) ? 1 : buffer.data.length,
              typedArrayConstructor: Float32Array,
              gpuBuffer: gpuBuffer.get(),
            };
          } else {
            if (buffer.isReferer) {
              // @ts-ignore
              if (buffer.data.model && buffer.data.model.outputBuffer) {
                // @ts-ignore
                gpuBuffer = (buffer.data.model as WebGPUComputeModel)
                  .outputBuffer;
              } else {
                // referred kernel haven't been executed
              }
            } else {
              gpuBuffer = new WebGPUBuffer(this.engine, {
                // @ts-ignore
                data: isFinite(Number(buffer.data))
                  ? [buffer.data]
                  : buffer.data,
                usage:
                  WebGPUConstants.BufferUsage.Storage |
                  WebGPUConstants.BufferUsage.CopyDst |
                  WebGPUConstants.BufferUsage.CopySrc,
              });
            }
          }

          this.vertexBuffers[buffer.name] = gpuBuffer;
          this.bindGroupEntries.push({
            binding: bufferBindingIndex,
            resource: {
              name: buffer.name,
              refer: gpuBuffer ? undefined : buffer.data,
              buffer: gpuBuffer ? gpuBuffer.get() : undefined,
            },
          });
          bufferBindingIndex++;
        }
      }
    });

    // create compute pipeline layout
    this.computePipeline = this.engine.device.createComputePipeline({
      computeStage,
    });

    console.log(this.bindGroupEntries);

    this.bindGroup = this.engine.device.createBindGroup({
      layout: this.computePipeline.getBindGroupLayout(0),
      entries: this.bindGroupEntries,
    });
  }